1 /* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright (C) 1995, 96, 97, 1998 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 This program allows you to build the files necessary to create
24 DLLs to run on a system which understands PE format image files.
27 See "Peering Inside the PE: A Tour of the Win32 Portable Executable
28 File Format", MSJ 1994, Volume 9 for more information.
29 Also see "Microsoft Portable Executable and Common Object File Format,
30 Specification 4.1" for more information.
32 A DLL contains an export table which contains the information
33 which the runtime loader needs to tie up references from a
36 The export table is generated by this program by reading
37 in a .DEF file or scanning the .a and .o files which will be in the
38 DLL. A .o file can contain information in special ".drectve" sections
39 with export information.
41 A DEF file contains any number of the following commands:
44 NAME <name> [ , <base> ]
45 The result is going to be <name>.EXE
47 LIBRARY <name> [ , <base> ]
48 The result is going to be <name>.DLL
50 EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] ) *
51 Declares name1 as an exported symbol from the
52 DLL, with optional ordinal number <integer>
54 IMPORTS ( [ <name> = ] <name> . <name> ) *
55 Ignored for compatibility
58 Puts <string> into output .exp file in the .rdata section
60 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
61 Generates --stack|--heap <number-reserve>,<number-commit>
62 in the output .drectve section. The linker will
63 see this and act upon it.
66 SECTIONS ( <sectionname> <attr>+ )*
67 <attr> = READ | WRITE | EXECUTE | SHARED
68 Generates --attr <sectionname> <attr> in the output
69 .drectve section. The linker will see this and act
73 A -export:<name> in a .drectve section in an input .o or .a
74 file to this program is equivalent to a EXPORTS <name>
79 The program generates output files with the prefix supplied
80 on the command line, or in the def file, or taken from the first
83 The .exp.s file contains the information necessary to export
84 the routines in the DLL. The .lib.s file contains the information
85 necessary to use the DLL's routines from a referencing program.
92 asm (".section .drectve");
93 asm (".ascii \"-export:adef\"");
97 printf("hello from the dll %s\n",s);
102 printf("hello from the dll and the other entry point %s\n",s);
106 asm (".section .drectve");
107 asm (".ascii \"-export:cdef\"");
108 asm (".ascii \"-export:ddef\"");
111 printf("hello from the dll %s\n",s);
116 printf("hello from the dll and the other entry point %s\n",s);
134 HEAPSIZE 0x40000, 0x2000
138 SECTIONS donkey READ WRITE
142 # compile up the parts of the dll
147 # put them in a library (you don't have to, you
148 # could name all the .os on the dlltool line)
150 ar qcv thedll.in file1.o file2.o
153 # run this tool over the library and the def file
154 ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
156 # build the dll with the library with file1.o, file2.o and the export table
157 ld -o thedll.dll thedll.o thedll.in
162 # link the executable with the import library
163 ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
167 /* .idata section description
169 The .idata section is the import table. It is a collection of several
170 subsections used to keep the pieces for each dll together: .idata$[234567].
171 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
173 .idata$2 = Import Directory Table
174 = array of IMAGE_IMPORT_DESCRIPTOR's.
176 DWORD Characteristics; - pointer to .idata$4
177 DWORD TimeDateStamp; - currently always 0
178 DWORD ForwarderChain; - currently always 0
179 DWORD Name; - pointer to dll's name
180 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
182 .idata$3 = null terminating entry for .idata$2.
184 .idata$4 = Import Lookup Table
185 = array of array of pointers to hint name table.
186 There is one for each dll being imported from, and each dll's set is
187 terminated by a trailing NULL.
189 .idata$5 = Import Address Table
190 = array of array of pointers to hint name table.
191 There is one for each dll being imported from, and each dll's set is
192 terminated by a trailing NULL.
193 Initially, this table is identical to the Import Lookup Table. However,
194 at load time, the loader overwrites the entries with the address of the
197 .idata$6 = Hint Name Table
198 = Array of { short, asciz } entries, one for each imported function.
199 The `short' is the function's ordinal number.
201 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)
204 /* AIX requires this to be the first thing in the file. */
211 #define show_allnames 0
213 #define PAGE_SIZE 4096
214 #define PAGE_MASK (-PAGE_SIZE)
216 #include "libiberty.h"
219 #include "demangle.h"
225 #ifdef HAVE_SYS_WAIT_H
226 #include <sys/wait.h>
227 #else /* ! HAVE_SYS_WAIT_H */
228 #if ! defined (_WIN32) || defined (__CYGWIN32__)
230 #define WIFEXITED(w) (((w)&0377) == 0)
233 #define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
236 #define WTERMSIG(w) ((w) & 0177)
239 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
241 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
243 #define WIFEXITED(w) (((w) & 0xff) == 0)
246 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
249 #define WTERMSIG(w) ((w) & 0x7f)
252 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
254 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
255 #endif /* ! HAVE_SYS_WAIT_H */
257 /* ifunc and ihead data structures: ttk@cygnus.com 1997
258 When IMPORT declarations are encountered in a .def file the
259 function import information is stored in a structure referenced
260 by the global variable "(iheadtype*) import_list". The struc-
261 ture is a linked list containing the names of the dll files
262 each function is imported from and a linked list of functions
263 being imported from that dll file. This roughly parallels the
264 structure of the .idata section in the PE object file.
265 The contents of .def file are interpreted from within the
266 process__def_file() function. Every time an IMPORT declaration
267 is encountered, it is broken up into its component parts and
268 passed to def_import(). import_list is initialized to NULL in
272 typedef struct ifunct
274 char *name; /* name of function being imported */
275 int ord; /* two-byte ordinal value associated with function */
280 typedef struct iheadt
282 char *dllname; /* name of dll file imported from */
283 long nfuncs; /* number of functions in list */
284 struct ifunct *funchead; /* first function in list */
285 struct ifunct *functail; /* last function in list */
286 struct iheadt *next; /* next dll file in list */
290 /* ignore_imports: if true, IMPORT declarations are ignored
291 and no .import section will be created.
292 import_list: structure containing all import information as
293 defined in .def file (qv "ihead structure").
294 nheads: count of number of dll files recorded in import_list.
297 static boolean ignore_imports = false;
298 static iheadtype *import_list = NULL;
301 static char *as_name = "as";
303 static int no_idata4;
304 static int no_idata5;
305 static char *exp_name;
306 static char *imp_name;
307 static char *head_label;
308 static char *imp_name_lab;
309 static char *dll_name;
311 static int add_indirect = 0;
312 static int add_underscore = 0;
313 static int dontdeltemps = 0;
315 static char *def_file;
317 static char *program_name;
322 static FILE *output_def;
323 static FILE *base_file;
326 static const char *mname = "arm";
330 static const char *mname = "i386";
334 static const char *mname = "ppc";
337 #define PATHMAX 250 /* What's the right name for this ? */
339 /* This bit of assemly does jmp * ....
340 s set how_jtab_roff to mark where the 32bit abs branch should go */
341 static const unsigned char i386_jtab[] =
343 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
346 static const unsigned char arm_jtab[] =
348 0x00, 0xc0, 0x9f, 0xe5,
349 0x00, 0xf0, 0x9c, 0xe5,
353 /* This is the glue sequence for PowerPC PE. There is a */
354 /* tocrel16-tocdefn reloc against the first instruction. */
355 /* We also need a IMGLUE reloc against the glue function */
356 /* to restore the toc saved by the third instruction in */
358 static const unsigned char ppc_jtab[] =
360 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
361 /* Reloc TOCREL16 __imp_xxx */
362 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
363 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
364 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
365 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
366 0x20, 0x04, 0x80, 0x4E /* bctr */
370 /* the glue instruction, picks up the toc from the stw in */
371 /* the above code: "lwz r2,4(r1)" */
372 static bfd_vma ppc_glue_insn = 0x80410004;
375 static char outfile[PATHMAX];
380 const char *how_byte;
381 const char *how_short;
382 const char *how_long;
383 const char *how_asciz;
384 const char *how_comment;
385 const char *how_jump;
386 const char *how_global;
387 const char *how_space;
388 const char *how_align_short;
389 const char *how_align_long;
390 const char *how_bfd_target;
391 enum bfd_architecture how_bfd_arch;
392 const unsigned char *how_jtab;
393 int how_jtab_size; /* size of the jtab entry */
394 int how_jtab_roff; /* offset into it for the ind 32 reloc into idata 5 */
397 static const struct mac mtable[] =
401 "arm", ".byte", ".short", ".long", ".asciz", "@",
402 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
403 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
404 arm_jtab, sizeof(arm_jtab),8
409 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386,
410 i386_jtab,sizeof(i386_jtab),2,
415 "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc,
416 ppc_jtab,sizeof(ppc_jtab),0,
429 typedef struct export
432 const char *internal_name;
442 static const char *rvaafter PARAMS ((int));
443 static const char *rvabefore PARAMS ((int));
444 static const char *asm_prefix PARAMS ((int));
445 static void run PARAMS ((const char *, char *));
446 static void basenames PARAMS ((bfd *));
447 static void scan_open_obj_file PARAMS ((bfd *));
448 static void scan_obj_file PARAMS ((const char *));
449 static void dump_def_info PARAMS ((FILE *));
450 static int sfunc PARAMS ((const void *, const void *));
451 static void flush_page PARAMS ((FILE *, long *, int, int));
452 static void gen_def_file PARAMS ((void));
453 static void gen_exp_file PARAMS ((void));
454 static const char *xlate PARAMS ((const char *));
455 static void dump_iat PARAMS ((FILE *, export_type *));
456 static char *make_label PARAMS ((const char *, const char *));
457 static bfd *make_one_lib_file PARAMS ((export_type *, int));
458 static bfd *make_head PARAMS ((void));
459 static bfd *make_tail PARAMS ((void));
460 static void gen_lib_file PARAMS ((void));
461 static int pfunc PARAMS ((const void *, const void *));
462 static int nfunc PARAMS ((const void *, const void *));
463 static void remove_null_names PARAMS ((export_type **));
464 static void dtab PARAMS ((export_type **));
465 static void process_duplicates PARAMS ((export_type **));
466 static void fill_ordinals PARAMS ((export_type **));
467 static int alphafunc PARAMS ((const void *, const void *));
468 static void mangle_defs PARAMS ((void));
469 static void usage PARAMS ((FILE *, int));
519 #define ASM_BYTE mtable[machine].how_byte
520 #define ASM_SHORT mtable[machine].how_short
521 #define ASM_LONG mtable[machine].how_long
522 #define ASM_TEXT mtable[machine].how_asciz
523 #define ASM_C mtable[machine].how_comment
524 #define ASM_JUMP mtable[machine].how_jump
525 #define ASM_GLOBAL mtable[machine].how_global
526 #define ASM_SPACE mtable[machine].how_space
527 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
528 #define ASM_RVA_BEFORE rvabefore(machine)
529 #define ASM_RVA_AFTER rvaafter(machine)
530 #define ASM_PREFIX asm_prefix(machine)
531 #define ASM_ALIGN_LONG mtable[machine].how_align_long
532 #define HOW_BFD_TARGET 0 /* always default*/
533 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
534 #define HOW_JTAB mtable[machine].how_jtab
535 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size
536 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
539 FILE *yyin; /* communications with flex */
540 extern int linenumber;
543 process_def_file (name)
546 FILE *f = fopen (name, FOPEN_RT);
549 fprintf (stderr, _("%s: Can't open def file %s\n"), program_name, name);
558 /**********************************************************************/
560 /* Communications with the parser */
562 static const char *d_name; /* Arg to NAME or LIBRARY */
563 static int d_nfuncs; /* Number of functions exported */
564 static int d_named_nfuncs; /* Number of named functions exported */
565 static int d_low_ord; /* Lowest ordinal index */
566 static int d_high_ord; /* Highest ordinal index */
567 static export_type *d_exports; /*list of exported functions */
568 static export_type **d_exports_lexically; /* vector of exported functions in alpha order */
569 static dlist_type *d_list; /* Descriptions */
570 static dlist_type *a_list; /* Stuff to go in directives */
579 fprintf (stderr, _("%s: Syntax error in def file %s:%d\n"),
580 program_name, def_file, linenumber);
585 def_exports (name, internal_name, ordinal, noname, constant, data)
587 const char *internal_name;
593 struct export *p = (struct export *) xmalloc (sizeof (*p));
596 p->internal_name = internal_name ? internal_name : name;
597 p->ordinal = ordinal;
598 p->constant = constant;
607 def_name (name, base)
612 fprintf (stderr, _("%s NAME %s base %x\n"), program_name, name, base);
615 fprintf (stderr, _("Can't have LIBRARY and NAME\n"));
622 def_library (name, base)
627 printf (_("%s: LIBRARY %s base %x\n"), program_name, name, base);
630 fprintf (stderr, _("%s: Can't have LIBRARY and NAME\n"), program_name);
637 def_description (desc)
640 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
641 d->text = xstrdup (desc);
650 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
651 d->text = xstrdup (dir);
657 def_heapsize (reserve, commit)
663 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
665 sprintf (b, "-heap 0x%x ", reserve);
666 new_directive (xstrdup (b));
670 def_stacksize (reserve, commit)
676 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
678 sprintf (b, "-stack 0x%x ", reserve);
679 new_directive (xstrdup (b));
682 /* append_import() simply adds the given import definition
683 to the global import_list. It is used by def_import().
686 append_import (symbol_name, dll_name, func_ordinal)
693 if (import_list == NULL)
695 import_list = xmalloc (sizeof (iheadtype));
696 import_list->dllname = xstrdup (dll_name);
697 import_list->nfuncs = 1;
698 import_list->funchead = xmalloc (sizeof (ifunctype));
699 import_list->functail = import_list->funchead;
700 import_list->next = NULL;
701 import_list->functail->name = xstrdup (symbol_name);
702 import_list->functail->ord = atoi (func_ordinal);
703 import_list->functail->next = NULL;
705 } /* END of case import_list == NULL */
706 headptr = import_list;
707 while ((strcmp (headptr->dllname,dll_name))
708 && (headptr->next != NULL))
709 headptr = headptr->next;
710 if (!strcmp (headptr->dllname, dll_name))
712 headptr->functail->next = xmalloc (sizeof (ifunctype));
713 headptr->functail = headptr->functail->next;
714 headptr->functail->ord = atoi (func_ordinal);
715 headptr->functail->name = xstrdup (symbol_name);
716 headptr->functail->next = NULL;
720 { /* this dll doesn't already have entry */
721 headptr->next = xmalloc (sizeof (iheadtype));
722 headptr = headptr->next;
723 headptr->dllname = xstrdup (dll_name);
725 headptr->funchead = xmalloc (sizeof (ifunctype));
726 headptr->functail = headptr->funchead;
727 headptr->next = NULL;
728 headptr->functail->name = xstrdup (symbol_name);
729 headptr->functail->ord = atoi (func_ordinal);
730 headptr->functail->next = NULL;
731 } /* END of if..else clause */
732 } /* END of function append_import */
734 /* def_import() is called from within defparse.y when an
735 IMPORT declaration is encountered. Depending on the
736 form of the declaration, the module name may or may not
737 need ".dll" to be appended to it, the name of the func-
738 tion may be stored in internal or entry, and there may
739 or may not be an ordinal value associated with it.
740 The interface between def_import() and append_import()
741 is a bit convoluted because append_import() was written
742 to handle a simpler case of IMPORT declaration and I
743 didn't have the time to rewrite it.
746 /* A note regarding the parse modes:
747 In yyparse.y we have to accept import declarations which
748 follow any one of the following forms:
749 <func_name_in_app> = <dll_name>.<func_name_in_dll>
750 <func_name_in_app> = <dll_name>.<number>
751 <dll_name>.<func_name_in_dll>
753 Furthermore, the dll's name may or may not end with ".dll",
754 which complicates the parsing a little. Normally the dll's
755 name is passed to def_import() in the "module" parameter,
756 but when it ends with ".dll" it gets passed in "module" sans
757 ".dll" and that needs to be reappended.
759 def_import() gets five parameters:
760 app_name - the name of the function in the application, if
761 present, or NULL if not present.
762 module - the name of the dll, possibly sans extension (ie, '.dll').
763 dllext - the extension of the dll, if present, NULL if not present.
764 entry - the name of the function in the dll, if present, or NULL.
765 ord_val - the numerical tag of the function in the dll, if present,
766 or NULL. Exactly one of <entry> or <ord_val> must be
767 present (ie, not NULL).
771 def_import (app_name, module, dllext, entry, ord_val)
776 int ord_val; /* two-byte value */
778 char *application_name;
782 char zero_str[1] = { 0 };
784 sprintf (ord_string, "%d", ord_val);
786 application_name = entry;
789 application_name = app_name;
791 application_name = zero_str;
794 module_name = (char*) alloca (strlen (module) + strlen(dllext) + 2);
795 sprintf (module_name, "%s.%s", module, dllext);
798 module_name = module;
799 entry_name = ord_string;
800 append_import (application_name, module_name, entry_name);
801 } /* END of function def_import */
804 def_version (major, minor)
808 printf ("VERSION %d.%d\n", major, minor);
812 def_section (name, attr)
829 sprintf (buf, "-attr %s %s", name, atts);
830 new_directive (xstrdup (buf));
838 def_section ("CODE", attr);
845 def_section ("DATA", attr);
848 /**********************************************************************/
856 int pid, wait_status;
859 char *errmsg_fmt, *errmsg_arg;
860 char *temp_base = choose_temp_base ();
863 fprintf (stderr, "%s %s\n", what, args);
867 for (s = args; *s; s++)
871 argv = alloca (sizeof (char *) * (i + 3));
878 while (*s != ' ' && *s != 0)
886 pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
887 &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
891 int errno_val = errno;
893 fprintf (stderr, "%s: ", program_name);
894 fprintf (stderr, errmsg_fmt, errmsg_arg);
895 fprintf (stderr, ": %s\n", strerror (errno_val));
899 pid = pwait (pid, &wait_status, 0);
902 fprintf (stderr, _("%s: wait: %s\n"), program_name, strerror (errno));
905 else if (WIFSIGNALED (wait_status))
907 fprintf (stderr, _("%s: subprocess got fatal signal %d\n"),
908 program_name, WTERMSIG (wait_status));
911 else if (WIFEXITED (wait_status))
913 if (WEXITSTATUS (wait_status) != 0)
914 fprintf (stderr, _("%s: %s exited with status %d\n"),
915 program_name, what, WEXITSTATUS (wait_status));
921 /* read in and block out the base relocations */
929 scan_open_obj_file (abfd)
932 /* Look for .drectve's */
933 asection *s = bfd_get_section_by_name (abfd, ".drectve");
936 int size = bfd_get_section_size_before_reloc (s);
937 char *buf = xmalloc (size);
940 bfd_get_section_contents (abfd, s, buf, 0, size);
942 fprintf (stderr, _("%s: Sucking in info from %s\n"),
944 bfd_get_filename (abfd));
946 /* Search for -export: strings */
952 && strncmp (p, "-export:", 8) == 0)
958 while (p < e && *p != ' ' && *p != '-')
960 c = xmalloc (p - name + 1);
961 memcpy (c, name, p - name);
963 /* FIXME: The 5th arg is for the `constant' field.
964 What should it be? Not that it matters since it's not
966 def_exports (c, 0, -1, 0, 0, 0);
977 fprintf (stderr, _("%s: Done readin\n"),
982 scan_obj_file (filename)
983 const char *filename;
985 bfd *f = bfd_openr (filename, 0);
989 fprintf (stderr, _("%s: Unable to open object file %s\n"),
994 if (bfd_check_format (f, bfd_archive))
996 bfd *arfile = bfd_openr_next_archived_file (f, 0);
999 if (bfd_check_format (arfile, bfd_object))
1000 scan_open_obj_file (arfile);
1002 arfile = bfd_openr_next_archived_file (f, arfile);
1005 else if (bfd_check_format (f, bfd_object))
1007 scan_open_obj_file (f);
1013 /**********************************************************************/
1021 fprintf (f, "%s ", ASM_C);
1022 for (i = 0; oav[i]; i++)
1023 fprintf (f, "%s ", oav[i]);
1025 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1027 fprintf (f, "%s %d = %s %s @ %d %s%s%s\n",
1033 exp->noname ? "NONAME " : "",
1034 exp->constant ? "CONSTANT" : "",
1035 exp->data ? "DATA" : "");
1039 /* Generate the .exp file */
1046 return *(const long *) a - *(const long *) b;
1050 flush_page (f, need, page_addr, on_page)
1058 /* Flush this page */
1059 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1063 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1065 (on_page * 2) + (on_page & 1) * 2 + 8,
1067 for (i = 0; i < on_page; i++)
1069 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (need[i] - page_addr) | 0x3000);
1073 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1082 fprintf (output_def, ";");
1083 for (i = 0; oav[i]; i++)
1084 fprintf (output_def, " %s", oav[i]);
1086 fprintf (output_def, "\nEXPORTS\n");
1088 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1090 char *quote = strchr (exp->name, '.') ? "\"" : "";
1091 fprintf (output_def, "\t%s%s%s @ %d%s%s ; %s\n",
1096 exp->noname ? " NONAME" : "",
1097 exp->data ? " DATA" : "",
1098 cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS));
1102 /* generate_idata_ofile() generates the portable assembly source code
1103 for the idata sections. It may be passed an open FILE* or a NULL.
1104 In the former case it appends the source code to the end of the
1105 file and returns NULL. In the latter case it creates a file named
1106 doi.s, assembles it to doi.o, opens doi.o as a bfd, and returns the
1107 bfd*. generate_idata_ofile() is currently used in the former manner
1112 generate_idata_ofile ( fd )
1126 filvar = fopen ("doi.s", "w");
1129 fprintf (stderr, "%s: Can't open doi.s\n", program_name);
1132 fprintf (filvar, "%s Import data sections\n", ASM_C);
1133 fprintf (filvar, "\n\t.section\t.idata$2\n");
1134 fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1135 fprintf (filvar, "doi_idata:\n");
1138 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1140 fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1141 ASM_RVA_BEFORE, (int)nheads, ASM_RVA_AFTER,
1142 ASM_C, headptr->dllname);
1143 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1144 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1145 fprintf (filvar, "\t%sdllname%d%s\n",
1146 ASM_RVA_BEFORE, (int)nheads, ASM_RVA_AFTER);
1147 fprintf (filvar, "\t%slisttwo%d%s\n\n",
1148 ASM_RVA_BEFORE, (int)nheads, ASM_RVA_AFTER);
1150 } /* END of headptr for-loop */
1152 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1153 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1154 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
1155 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1156 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1158 fprintf (filvar, "\n\t.section\t.idata$4\n");
1160 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1162 fprintf (filvar, "listone%d:\n", headindex);
1163 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1164 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1165 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1166 fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1168 } /* END of headptr for loop */
1170 fprintf (filvar, "\n\t.section\t.idata$5\n");
1172 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1174 fprintf (filvar, "listtwo%d:\n", headindex);
1175 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1176 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1177 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1178 fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1180 } /* END of headptr for-loop */
1182 fprintf (filvar, "\n\t.section\t.idata$6\n");
1184 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1187 for (funcptr = headptr->funchead; funcptr != NULL;
1188 funcptr = funcptr->next)
1190 fprintf (filvar,"funcptr%d_%d:\n",headindex,funcindex);
1191 fprintf (filvar,"\t%s\t%d\n",ASM_SHORT,((funcptr->ord) & 0xFFFF));
1192 fprintf (filvar,"\t%s\t%c%s%c\n",ASM_TEXT,'"',funcptr->name,'"');
1193 fprintf (filvar,"\t%s\t0\n",ASM_BYTE);
1195 } /* END of funcptr for loop */
1197 } /* END of headptr for loop */
1199 fprintf (filvar, "\n\t.section\t.idata$7\n");
1201 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1203 fprintf (filvar,"dllname%d:\n",headindex);
1204 fprintf (filvar,"\t%s\t%c%s%c\n",ASM_TEXT,'"',headptr->dllname,'"');
1205 fprintf (filvar,"\t%s\t0\n",ASM_BYTE);
1207 } /* END of headptr for loop */
1211 result = fclose (filvar);
1214 fprintf (stderr, "%s: Can't close doi.s\n", program_name);
1216 } /* END of if clause */
1217 sprintf (as_args, "-o doi.o doi.s");
1218 run (as_name, as_args);
1220 if (dontdeltemps == 0)
1222 sprintf (outfile, "doi.s");
1225 return (bfd_openr ("doi.o", HOW_BFD_TARGET));
1226 } /* END of if clause */
1229 } /* END of function generate_idata_ofile() */
1241 sprintf (outfile, "t%s", exp_name);
1244 fprintf (stderr, _("%s: Generate exp file %s\n"),
1245 program_name, exp_name);
1247 f = fopen (outfile, FOPEN_WT);
1250 fprintf (stderr, _("%s: Unable to open output file %s\n"), program_name, outfile);
1255 fprintf (stderr, _("%s: Opened file %s\n"),
1256 program_name, outfile);
1262 fprintf (f, "\t.section .edata\n\n");
1263 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
1264 fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG, (long) time(0),
1266 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
1267 fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1268 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
1271 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
1272 fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
1274 d_named_nfuncs, d_low_ord, d_high_ord);
1275 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
1276 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
1277 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1279 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
1280 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1282 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1284 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
1287 fprintf(f,"%s Export address Table\n", ASM_C);
1288 fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
1289 fprintf (f, "afuncs:\n");
1292 for (exp = d_exports; exp; exp = exp->next)
1294 if (exp->ordinal != i)
1297 fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
1299 (exp->ordinal - i) * 4,
1301 i, exp->ordinal - 1);
1304 while (i < exp->ordinal)
1306 fprintf(f,"\t%s\t0\n", ASM_LONG);
1310 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
1312 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1316 fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
1317 fprintf (f, "anames:\n");
1319 for (i = 0; (exp = d_exports_lexically[i]); i++)
1321 if (!exp->noname || show_allnames)
1322 fprintf (f, "\t%sn%d%s\n", ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
1325 fprintf (f,"%s Export Oridinal Table\n", ASM_C);
1326 fprintf (f, "anords:\n");
1327 for (i = 0; (exp = d_exports_lexically[i]); i++)
1329 if (!exp->noname || show_allnames)
1330 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
1333 fprintf(f,"%s Export Name Table\n", ASM_C);
1334 for (i = 0; (exp = d_exports_lexically[i]); i++)
1335 if (!exp->noname || show_allnames)
1336 fprintf (f, "n%d: %s \"%s\"\n", exp->ordinal, ASM_TEXT, exp->name);
1340 fprintf (f, "\t.section .drectve\n");
1341 for (dl = a_list; dl; dl = dl->next)
1343 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1348 fprintf (f, "\t.section .rdata\n");
1349 for (dl = d_list; dl; dl = dl->next)
1353 /* We dont output as ascii 'cause there can
1354 be quote characters in the string */
1357 for (p = dl->text; *p; p++)
1360 fprintf (f, "\t%s\t", ASM_BYTE);
1363 fprintf (f, "%d", *p);
1366 fprintf (f, ",0\n");
1380 /* Add to the output file a way of getting to the exported names
1381 without using the import library. */
1384 fprintf (f, "\t.section\t.rdata\n");
1385 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1386 if (!exp->noname || show_allnames)
1388 /* We use a single underscore for MS compatibility, and a
1389 double underscore for backward compatibility with old
1391 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1392 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1393 fprintf (f, "__imp_%s:\n", exp->name);
1394 fprintf (f, "_imp__%s:\n", exp->name);
1395 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1399 /* Dump the reloc section if a base file is provided */
1403 long need[PAGE_SIZE];
1410 fprintf (f, "\t.section\t.init\n");
1411 fprintf (f, "lab:\n");
1413 fseek (base_file, 0, SEEK_END);
1414 numbytes = ftell (base_file);
1415 fseek (base_file, 0, SEEK_SET);
1416 copy = xmalloc (numbytes);
1417 fread (copy, 1, numbytes, base_file);
1418 num_entries = numbytes / sizeof (long);
1421 fprintf (f, "\t.section\t.reloc\n");
1427 qsort (copy, num_entries, sizeof (long), sfunc);
1428 /* Delete duplcates */
1429 for (src = 0; src < num_entries; src++)
1431 if (last != copy[src])
1432 last = copy[dst++] = copy[src];
1436 page_addr = addr & PAGE_MASK; /* work out the page addr */
1438 for (j = 0; j < num_entries; j++)
1441 if ((addr & PAGE_MASK) != page_addr)
1443 flush_page (f, need, page_addr, on_page);
1445 page_addr = addr & PAGE_MASK;
1447 need[on_page++] = addr;
1449 flush_page (f, need, page_addr, on_page);
1451 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1455 result = generate_idata_ofile (f);
1456 if ( result != NULL )
1458 fprintf (stderr, "%s: error writing idata section\n",
1465 /* assemble the file */
1466 sprintf (outfile, "-o %s t%s", exp_name, exp_name);
1467 run (as_name, outfile);
1468 if (dontdeltemps == 0)
1470 sprintf (outfile, "t%s", exp_name);
1481 char *copy = xmalloc (strlen (name) + 2);
1483 strcpy (copy + 1, name);
1490 p = strchr (name, '@');
1497 /**********************************************************************/
1504 if (exp->noname && !show_allnames )
1506 fprintf (f, "\t%s\t0x%08x\n",
1508 exp->ordinal | 0x80000000); /* hint or orindal ?? */
1512 fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
1528 unsigned char *data;
1543 static sinfo secdata[NSECS] =
1545 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 2},
1546 { DATA, ".data", SEC_DATA, 2},
1547 { BSS, ".bss", 0, 2},
1548 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1549 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1550 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1551 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}
1556 /* Sections numbered to make the order the same as other PowerPC NT */
1557 /* compilers. This also keeps funny alignment thingies from happening. */
1570 static sinfo secdata[NSECS] =
1572 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
1573 { PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
1574 { RDATA, ".reldata", SEC_HAS_CONTENTS, 2},
1575 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1576 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1577 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1},
1578 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1579 { DATA, ".data", SEC_DATA, 2},
1580 { BSS, ".bss", 0, 2}
1586 This is what we're trying to make. We generate the imp symbols with
1587 both single and double underscores, for compatibility.
1590 .global _GetFileVersionInfoSizeW@8
1591 .global __imp_GetFileVersionInfoSizeW@8
1592 _GetFileVersionInfoSizeW@8:
1593 jmp * __imp_GetFileVersionInfoSizeW@8
1594 .section .idata$7 # To force loading of head
1595 .long __version_a_head
1596 # Import Address Table
1598 __imp_GetFileVersionInfoSizeW@8:
1601 # Import Lookup Table
1607 .asciz "GetFileVersionInfoSizeW"
1610 For the PowerPC, here's the variation on the above scheme:
1612 # Rather than a simple "jmp *", the code to get to the dll function
1615 lwz r11,[tocv]__imp_function_name(r2)
1616 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
1625 make_label (prefix, name)
1629 int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
1630 char *copy = xmalloc (len +1 );
1631 strcpy (copy, ASM_PREFIX);
1632 strcat (copy, prefix);
1633 strcat (copy, name);
1638 make_one_lib_file (exp, i)
1646 sprintf (outfile, "%ss%d.s", prefix, i);
1647 f = fopen (outfile, FOPEN_WT);
1648 fprintf (f, "\t.text\n");
1649 fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name);
1650 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1651 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1652 fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
1653 exp->name, ASM_JUMP, exp->name);
1655 fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
1656 fprintf (f, "\t%s\t%s\n", ASM_LONG, head_label);
1659 fprintf (f,"%s Import Address Table\n", ASM_C);
1661 fprintf (f, "\t.section .idata$5\n");
1662 fprintf (f, "__imp_%s:\n", exp->name);
1663 fprintf (f, "_imp__%s:\n", exp->name);
1667 fprintf (f, "\n%s Import Lookup Table\n", ASM_C);
1668 fprintf (f, "\t.section .idata$4\n");
1672 if(!exp->noname || show_allnames)
1674 fprintf (f, "%s Hint/Name table\n", ASM_C);
1675 fprintf (f, "\t.section .idata$6\n");
1676 fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
1677 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
1683 sprintf (outfile, "-o %ss%d.o %ss%d.s", prefix, i, prefix, i);
1685 run (as_name, outfile);
1694 asymbol *iname, *iname2;
1696 asymbol **iname_lab_pp;
1699 /* Extra Symbols for PPC */
1711 asymbol *ptrs[NSECS + 4 + EXTRA + 1];
1713 char *outname = xmalloc (10);
1715 sprintf (outname, "ds%d.o", i);
1716 abfd = bfd_openw (outname, HOW_BFD_TARGET);
1719 fprintf (stderr, _("%s: bfd_open failed open output file %s\n"),
1720 program_name, outname);
1724 bfd_set_format (abfd, bfd_object);
1725 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
1728 /* First make symbols for the sections */
1729 for (i = 0; i < NSECS; i++)
1731 sinfo *si = secdata + i;
1734 si->sec = bfd_make_section_old_way (abfd, si->name);
1735 bfd_set_section_flags (abfd,
1739 bfd_set_section_alignment(abfd, si->sec, si->align);
1740 si->sec->output_section = si->sec;
1741 si->sym = bfd_make_empty_symbol(abfd);
1742 si->sym->name = si->sec->name;
1743 si->sym->section = si->sec;
1744 si->sym->flags = BSF_LOCAL;
1746 ptrs[oidx] = si->sym;
1747 si->sympp = ptrs + oidx;
1756 exp_label = bfd_make_empty_symbol (abfd);
1757 exp_label->name = make_label ("", exp->name);
1759 /* On PowerPC, the function name points to a descriptor in
1760 the rdata section, the first element of which is a
1761 pointer to the code (..function_name), and the second
1762 points to the .toc */
1764 if (machine == MPPC)
1765 exp_label->section = secdata[RDATA].sec;
1768 exp_label->section = secdata[TEXT].sec;
1770 exp_label->flags = BSF_GLOBAL;
1771 exp_label->value = 0;
1773 ptrs[oidx++] = exp_label;
1776 /* Generate imp symbols with one underscore for Microsoft
1777 compatibility, and with two underscores for backward
1778 compatibility with old versions of cygwin. */
1779 iname = bfd_make_empty_symbol(abfd);
1780 iname->name = make_label ("__imp_", exp->name);
1781 iname->section = secdata[IDATA5].sec;
1782 iname->flags = BSF_GLOBAL;
1785 iname2 = bfd_make_empty_symbol(abfd);
1786 iname2->name = make_label ("_imp__", exp->name);
1787 iname2->section = secdata[IDATA5].sec;
1788 iname2->flags = BSF_GLOBAL;
1791 iname_lab = bfd_make_empty_symbol(abfd);
1793 iname_lab->name = head_label;
1794 iname_lab->section = (asection *)&bfd_und_section;
1795 iname_lab->flags = 0;
1796 iname_lab->value = 0;
1799 iname_pp = ptrs + oidx;
1800 ptrs[oidx++] = iname;
1801 ptrs[oidx++] = iname2;
1803 iname_lab_pp = ptrs + oidx;
1804 ptrs[oidx++] = iname_lab;
1807 /* The symbol refering to the code (.text) */
1809 asymbol *function_name;
1811 function_name = bfd_make_empty_symbol(abfd);
1812 function_name->name = make_label ("..", exp->name);
1813 function_name->section = secdata[TEXT].sec;
1814 function_name->flags = BSF_GLOBAL;
1815 function_name->value = 0;
1817 fn_pp = ptrs + oidx;
1818 ptrs[oidx++] = function_name;
1821 /* The .toc symbol */
1823 asymbol *toc_symbol; /* The .toc symbol */
1825 toc_symbol = bfd_make_empty_symbol(abfd);
1826 toc_symbol->name = make_label (".", "toc");
1827 toc_symbol->section = (asection *)&bfd_und_section;
1828 toc_symbol->flags = BSF_GLOBAL;
1829 toc_symbol->value = 0;
1831 toc_pp = ptrs + oidx;
1832 ptrs[oidx++] = toc_symbol;
1838 for (i = 0; i < NSECS; i++)
1840 sinfo *si = secdata + i;
1841 asection *sec = si->sec;
1850 si->size = HOW_JTAB_SIZE;
1851 si->data = xmalloc (HOW_JTAB_SIZE);
1852 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
1854 /* add the reloqc into idata$5 */
1855 rel = xmalloc (sizeof (arelent));
1856 rpp = xmalloc (sizeof (arelent *) * 2);
1859 rel->address = HOW_JTAB_ROFF;
1862 if (machine == MPPC)
1864 rel->howto = bfd_reloc_type_lookup (abfd,
1865 BFD_RELOC_16_GOTOFF);
1866 rel->sym_ptr_ptr = iname_pp;
1870 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1871 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
1873 sec->orelocation = rpp;
1874 sec->reloc_count = 1;
1879 /* An idata$4 or idata$5 is one word long, and has an
1882 si->data = xmalloc (4);
1887 si->data[0] = exp->ordinal ;
1888 si->data[1] = exp->ordinal >> 8;
1889 si->data[2] = exp->ordinal >> 16;
1894 sec->reloc_count = 1;
1895 memset (si->data, 0, si->size);
1896 rel = xmalloc (sizeof (arelent));
1897 rpp = xmalloc (sizeof (arelent *) * 2);
1902 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
1903 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
1904 sec->orelocation = rpp;
1912 /* This used to add 1 to exp->hint. I don't know
1913 why it did that, and it does not match what I see
1914 in programs compiled with the MS tools. */
1915 int idx = exp->hint;
1916 si->size = strlen (xlate (exp->name)) + 3;
1917 si->data = xmalloc (si->size);
1918 si->data[0] = idx & 0xff;
1919 si->data[1] = idx >> 8;
1920 strcpy (si->data + 2, xlate (exp->name));
1925 si->data =xmalloc(4);
1926 memset (si->data, 0, si->size);
1927 rel = xmalloc (sizeof (arelent));
1928 rpp = xmalloc (sizeof (arelent *) * 2);
1932 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
1933 rel->sym_ptr_ptr = iname_lab_pp;
1934 sec->orelocation = rpp;
1935 sec->reloc_count = 1;
1941 /* The .pdata section is 5 words long. */
1942 /* Think of it as: */
1945 /* bfd_vma BeginAddress, [0x00] */
1946 /* EndAddress, [0x04] */
1947 /* ExceptionHandler, [0x08] */
1948 /* HandlerData, [0x0c] */
1949 /* PrologEndAddress; [0x10] */
1952 /* So this pdata section setups up this as a glue linkage to
1953 a dll routine. There are a number of house keeping things
1956 1. In the name of glue trickery, the ADDR32 relocs for 0,
1957 4, and 0x10 are set to point to the same place:
1959 2. There is one more reloc needed in the pdata section.
1960 The actual glue instruction to restore the toc on
1961 return is saved as the offset in an IMGLUE reloc.
1962 So we need a total of four relocs for this section.
1964 3. Lastly, the HandlerData field is set to 0x03, to indicate
1965 that this is a glue routine.
1967 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
1969 /* alignment must be set to 2**2 or you get extra stuff */
1970 bfd_set_section_alignment(abfd, sec, 2);
1973 si->data =xmalloc(4 * 5);
1974 memset (si->data, 0, si->size);
1975 rpp = xmalloc (sizeof (arelent *) * 5);
1976 rpp[0] = imglue = xmalloc (sizeof (arelent));
1977 rpp[1] = ba_rel = xmalloc (sizeof (arelent));
1978 rpp[2] = ea_rel = xmalloc (sizeof (arelent));
1979 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
1982 /* stick the toc reload instruction in the glue reloc */
1983 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
1986 imglue->howto = bfd_reloc_type_lookup (abfd,
1987 BFD_RELOC_32_GOTOFF);
1988 imglue->sym_ptr_ptr = fn_pp;
1990 ba_rel->address = 0;
1992 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1993 ba_rel->sym_ptr_ptr = fn_pp;
1995 bfd_put_32(abfd, 0x18, si->data + 0x04);
1996 ea_rel->address = 4;
1998 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1999 ea_rel->sym_ptr_ptr = fn_pp;
2001 /* mark it as glue */
2002 bfd_put_32(abfd, 0x03, si->data + 0x0c);
2004 /* mark the prolog end address */
2005 bfd_put_32(abfd, 0x0D, si->data + 0x10);
2006 pea_rel->address = 0x10;
2007 pea_rel->addend = 0;
2008 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2009 pea_rel->sym_ptr_ptr = fn_pp;
2011 sec->orelocation = rpp;
2012 sec->reloc_count = 4;
2016 /* Each external function in a PowerPC PE file has a two word
2017 descriptor consisting of:
2018 1. The address of the code.
2019 2. The address of the appropriate .toc
2020 We use relocs to build this.
2024 si->data = xmalloc (8);
2025 memset (si->data, 0, si->size);
2027 rpp = xmalloc (sizeof (arelent *) * 3);
2028 rpp[0] = rel = xmalloc (sizeof (arelent));
2029 rpp[1] = xmalloc (sizeof (arelent));
2034 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2035 rel->sym_ptr_ptr = fn_pp;
2041 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2042 rel->sym_ptr_ptr = toc_pp;
2044 sec->orelocation = rpp;
2045 sec->reloc_count = 2;
2047 #endif /* DLLTOOL_PPC */
2053 /* Size up all the sections */
2054 for (i = 0; i < NSECS; i++)
2056 sinfo *si = secdata + i;
2058 bfd_set_section_size (abfd, si->sec, si->size);
2059 bfd_set_section_vma (abfd, si->sec, vma);
2061 /* vma += si->size;*/
2064 /* Write them out */
2065 for (i = 0; i < NSECS; i++)
2067 sinfo *si = secdata + i;
2069 if (i == IDATA5 && no_idata5)
2072 if (i == IDATA4 && no_idata4)
2075 bfd_set_section_contents (abfd, si->sec,
2080 bfd_set_symtab (abfd, ptrs, oidx);
2082 abfd = bfd_openr (outname, HOW_BFD_TARGET);
2091 FILE * f = fopen ("dh.s", FOPEN_WT);
2093 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2094 fprintf (f, "\t.section .idata$2\n");
2096 fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
2098 fprintf (f, "%s:\n", head_label);
2100 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2101 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2103 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2104 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2105 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2106 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2107 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2112 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2114 ASM_RVA_AFTER, ASM_C);
2116 fprintf (f, "%sStuff for compatibility\n", ASM_C);
2120 fprintf (f, "\t.section\t.idata$5\n");
2121 fprintf (f, "\t%s\t0\n", ASM_LONG);
2122 fprintf (f, "fthunk:\n");
2126 fprintf (f, "\t.section\t.idata$4\n");
2128 fprintf (f, "\t%s\t0\n", ASM_LONG);
2129 fprintf (f, "\t.section .idata$4\n");
2130 fprintf (f, "hname:\n");
2134 sprintf (outfile, "-o dh.o dh.s");
2135 run (as_name, outfile);
2137 return bfd_openr ("dh.o", HOW_BFD_TARGET);
2143 FILE * f = fopen ("dt.s", FOPEN_WT);
2147 fprintf (f, "\t.section .idata$4\n");
2148 fprintf (f, "\t%s\t0\n", ASM_LONG);
2152 fprintf (f, "\t.section .idata$5\n");
2153 fprintf (f, "\t%s\t0\n", ASM_LONG);
2157 /* Normally, we need to see a null descriptor built in idata$3 to
2158 act as the terminator for the list. The ideal way, I suppose,
2159 would be to mark this section as a comdat type 2 section, so
2160 only one would appear in the final .exe (if our linker supported
2161 comdat, that is) or cause it to be inserted by something else (say
2165 fprintf (f, "\t.section .idata$3\n");
2166 fprintf (f, "\t%s\t0\n", ASM_LONG);
2167 fprintf (f, "\t%s\t0\n", ASM_LONG);
2168 fprintf (f, "\t%s\t0\n", ASM_LONG);
2169 fprintf (f, "\t%s\t0\n", ASM_LONG);
2170 fprintf (f, "\t%s\t0\n", ASM_LONG);
2174 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2175 do too. Original, huh? */
2176 fprintf (f, "\t.section .idata$6\n");
2178 fprintf (f, "\t.section .idata$7\n");
2181 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
2182 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
2183 imp_name_lab, ASM_TEXT, dll_name);
2187 sprintf (outfile, "-o dt.o dt.s");
2188 run (as_name, outfile);
2189 return bfd_openr ("dt.o", HOW_BFD_TARGET);
2204 outarch = bfd_openw (imp_name, HOW_BFD_TARGET);
2208 fprintf (stderr, _("%s: Can't open .lib file %s\n"),
2209 program_name, imp_name);
2212 bfd_set_format (outarch, bfd_archive);
2213 outarch->has_armap = 1;
2215 /* Work out a reasonable size of things to put onto one line. */
2219 ar_head = make_head ();
2220 ar_tail = make_tail();
2222 for (i = 0; (exp = d_exports_lexically[i]); i++)
2224 bfd *n = make_one_lib_file (exp, i);
2230 /* Now stick them all into the archive */
2232 ar_head->next = head;
2233 ar_tail->next = ar_head;
2236 if (! bfd_set_archive_head (outarch, head))
2237 bfd_fatal ("bfd_set_archive_head");
2238 if (! bfd_close (outarch))
2239 bfd_fatal (imp_name);
2241 while (head != NULL)
2243 bfd *n = head->next;
2248 /* Delete all the temp files */
2250 if (dontdeltemps == 0)
2252 sprintf (outfile, "dh.o");
2254 sprintf (outfile, "dh.s");
2256 sprintf (outfile, "dt.o");
2258 sprintf (outfile, "dt.s");
2262 if (dontdeltemps < 2)
2264 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2266 sprintf (outfile, "ds%d.o",i);
2267 if (unlink (outfile) < 0)
2268 fprintf (stderr, _("%s: cannot delete %s: %s\n"), program_name,
2269 outfile, strerror (errno));
2274 /**********************************************************************/
2276 /* Run through the information gathered from the .o files and the
2277 .def file and work out the best stuff */
2283 export_type *ap = *(export_type **) a;
2284 export_type *bp = *(export_type **) b;
2285 if (ap->ordinal == bp->ordinal)
2288 /* unset ordinals go to the bottom */
2289 if (ap->ordinal == -1)
2291 if (bp->ordinal == -1)
2293 return (ap->ordinal - bp->ordinal);
2301 export_type *ap = *(export_type **) a;
2302 export_type *bp = *(export_type **) b;
2304 return (strcmp (ap->name, bp->name));
2308 remove_null_names (ptr)
2313 for (dst = src = 0; src < d_nfuncs; src++)
2317 ptr[dst] = ptr[src];
2330 for (i = 0; i < d_nfuncs; i++)
2334 printf ("%d %s @ %d %s%s%s\n",
2335 i, ptr[i]->name, ptr[i]->ordinal,
2336 ptr[i]->noname ? "NONAME " : "",
2337 ptr[i]->constant ? "CONSTANT" : "",
2338 ptr[i]->data ? "DATA" : "");
2347 process_duplicates (d_export_vec)
2348 export_type **d_export_vec;
2356 /* Remove duplicates */
2357 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
2359 dtab (d_export_vec);
2360 for (i = 0; i < d_nfuncs - 1; i++)
2362 if (strcmp (d_export_vec[i]->name,
2363 d_export_vec[i + 1]->name) == 0)
2366 export_type *a = d_export_vec[i];
2367 export_type *b = d_export_vec[i + 1];
2371 fprintf (stderr, _("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2375 if (a->ordinal != -1
2376 && b->ordinal != -1)
2379 fprintf (stderr, _("Error, duplicate EXPORT with oridinals %s\n"),
2383 /* Merge attributes */
2384 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
2385 b->constant |= a->constant;
2386 b->noname |= a->noname;
2388 d_export_vec[i] = 0;
2391 dtab (d_export_vec);
2392 remove_null_names (d_export_vec);
2393 dtab (d_export_vec);
2398 /* Count the names */
2399 for (i = 0; i < d_nfuncs; i++)
2401 if (!d_export_vec[i]->noname)
2407 fill_ordinals (d_export_vec)
2408 export_type **d_export_vec;
2415 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2417 /* fill in the unset ordinals with ones from our range */
2419 ptr = (char *) xmalloc (size);
2421 memset (ptr, 0, size);
2423 /* Mark in our large vector all the numbers that are taken */
2424 for (i = 0; i < d_nfuncs; i++)
2426 if (d_export_vec[i]->ordinal != -1)
2428 ptr[d_export_vec[i]->ordinal] = 1;
2429 if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
2431 lowest = d_export_vec[i]->ordinal;
2436 /* Start at 1 for compatibility with MS toolchain. */
2440 /* Now fill in ordinals where the user wants us to choose. */
2441 for (i = 0; i < d_nfuncs; i++)
2443 if (d_export_vec[i]->ordinal == -1)
2447 /* First try within or after any user supplied range. */
2448 for (j = lowest; j < size; j++)
2452 d_export_vec[i]->ordinal = j;
2456 /* Then try before the range. */
2457 for (j = lowest; j >0; j--)
2461 d_export_vec[i]->ordinal = j;
2472 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2474 /* Work out the lowest and highest ordinal numbers. */
2477 if (d_export_vec[0])
2478 d_low_ord = d_export_vec[0]->ordinal;
2479 if (d_export_vec[d_nfuncs-1])
2480 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
2489 const export_type **a = (const export_type **) av;
2490 const export_type **b = (const export_type **) bv;
2492 return strcmp ((*a)->name, (*b)->name);
2498 /* First work out the minimum ordinal chosen */
2504 export_type **d_export_vec
2505 = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
2507 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2509 d_export_vec[i] = exp;
2512 process_duplicates (d_export_vec);
2513 fill_ordinals (d_export_vec);
2515 /* Put back the list in the new order */
2517 for (i = d_nfuncs - 1; i >= 0; i--)
2519 d_export_vec[i]->next = d_exports;
2520 d_exports = d_export_vec[i];
2523 /* Build list in alpha order */
2524 d_exports_lexically = (export_type **)xmalloc (sizeof(export_type *)*(d_nfuncs+1));
2526 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2528 d_exports_lexically[i] = exp;
2530 d_exports_lexically[i] = 0;
2532 qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
2534 /* Fill exp entries with their hint values */
2536 for (i = 0; i < d_nfuncs; i++)
2538 if (!d_exports_lexically[i]->noname || show_allnames)
2539 d_exports_lexically[i]->hint = hint++;
2544 /**********************************************************************/
2547 usage (file, status)
2551 fprintf (file, _("Usage %s <options> <object-files>\n"), program_name);
2552 fprintf (file, _(" --machine <machine>\n"));
2553 fprintf (file, _(" --output-exp <outname> Generate export file.\n"));
2554 fprintf (file, _(" --output-lib <outname> Generate input library.\n"));
2555 fprintf (file, _(" --add-indirect Add dll indirects to export file.\n"));
2556 fprintf (file, _(" --dllname <name> Name of input dll to put into output lib.\n"));
2557 fprintf (file, _(" --def <deffile> Name input .def file\n"));
2558 fprintf (file, _(" --output-def <deffile> Name output .def file\n"));
2559 fprintf (file, _(" --base-file <basefile> Read linker generated base file\n"));
2560 fprintf (file, _(" --no-idata4 Don't generate idata$4 section\n"));
2561 fprintf (file, _(" --no-idata5 Don't generate idata$5 section\n"));
2562 fprintf (file, _(" -v Verbose\n"));
2563 fprintf (file, _(" -U Add underscores to .lib\n"));
2564 fprintf (file, _(" -k Kill @<n> from exported names\n"));
2565 fprintf (file, _(" --as <name> Use <name> for assembler\n"));
2566 fprintf (file, _(" --nodelete Keep temp files.\n"));
2570 #define OPTION_NO_IDATA4 'x'
2571 #define OPTION_NO_IDATA5 'c'
2572 static const struct option long_options[] =
2574 {"nodelete", no_argument, NULL, 'n'},
2575 {"dllname", required_argument, NULL, 'D'},
2576 {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
2577 {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
2578 {"output-exp", required_argument, NULL, 'e'},
2579 {"output-def", required_argument, NULL, 'z'},
2580 {"output-lib", required_argument, NULL, 'l'},
2581 {"def", required_argument, NULL, 'd'},
2582 {"add-underscore", no_argument, NULL, 'U'},
2583 {"killat", no_argument, NULL, 'k'},
2584 {"help", no_argument, NULL, 'h'},
2585 {"machine", required_argument, NULL, 'm'},
2586 {"add-indirect", no_argument, NULL, 'a'},
2587 {"base-file", required_argument, NULL, 'b'},
2588 {"as", required_argument, NULL, 'S'},
2600 program_name = av[0];
2603 setlocale (LC_MESSAGES, "");
2604 bindtextdomain (PACKAGE, LOCALEDIR);
2605 textdomain (PACKAGE);
2607 while ((c = getopt_long (ac, av, "xcz:S:R:A:puaD:l:e:nkvbUh?m:yd:", long_options, 0))
2612 case OPTION_NO_IDATA4:
2615 case OPTION_NO_IDATA5:
2622 /* ignored for compatibility */
2629 output_def = fopen (optarg, FOPEN_WT);
2652 /* We don't currently define YYDEBUG when building
2670 base_file = fopen (optarg, FOPEN_RB);
2673 fprintf (stderr, _("%s: Unable to open base-file %s\n"),
2685 for (i = 0; mtable[i].type; i++)
2687 if (strcmp (mtable[i].type, mname) == 0)
2691 if (!mtable[i].type)
2693 fprintf (stderr, _("Machine not supported\n"));
2699 if (!dll_name && exp_name)
2701 int len = strlen (exp_name) + 5;
2702 dll_name = xmalloc (len);
2703 strcpy (dll_name, exp_name);
2704 strcat (dll_name, ".dll");
2709 process_def_file (def_file);
2714 firstarg = av[optind];
2715 scan_obj_file (av[optind]);
2725 /* Make imp_name safe for use as a label. */
2728 imp_name_lab = xstrdup (imp_name);
2729 for (p = imp_name_lab; *p; p++)
2731 if (!isalpha (*p) && !isdigit (*p))
2734 head_label = make_label("_head_", imp_name_lab);