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 ( ( <internal-name> = <module-name> . <integer> )
55 | ( [ <internal-name> = ] <module-name> . <external-name> )) *
56 Declares that <external-name> or the exported function whoes ordinal number
57 is <integer> is to be imported from the file <module-name>. If
58 <internal-name> is specified then this is the name that the imported
59 function will be refered to in the body of the DLL.
62 Puts <string> into output .exp file in the .rdata section
64 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
65 Generates --stack|--heap <number-reserve>,<number-commit>
66 in the output .drectve section. The linker will
67 see this and act upon it.
70 SECTIONS ( <sectionname> <attr>+ )*
71 <attr> = READ | WRITE | EXECUTE | SHARED
72 Generates --attr <sectionname> <attr> in the output
73 .drectve section. The linker will see this and act
77 A -export:<name> in a .drectve section in an input .o or .a
78 file to this program is equivalent to a EXPORTS <name>
83 The program generates output files with the prefix supplied
84 on the command line, or in the def file, or taken from the first
87 The .exp.s file contains the information necessary to export
88 the routines in the DLL. The .lib.s file contains the information
89 necessary to use the DLL's routines from a referencing program.
96 asm (".section .drectve");
97 asm (".ascii \"-export:adef\"");
101 printf ("hello from the dll %s\n", s);
106 printf ("hello from the dll and the other entry point %s\n", s);
110 asm (".section .drectve");
111 asm (".ascii \"-export:cdef\"");
112 asm (".ascii \"-export:ddef\"");
116 printf ("hello from the dll %s\n", s);
121 printf ("hello from the dll and the other entry point %s\n", s);
139 HEAPSIZE 0x40000, 0x2000
143 SECTIONS donkey READ WRITE
146 # compile up the parts of the dll
151 # put them in a library (you don't have to, you
152 # could name all the .os on the dlltool line)
154 ar qcv thedll.in file1.o file2.o
157 # run this tool over the library and the def file
158 ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
160 # build the dll with the library with file1.o, file2.o and the export table
161 ld -o thedll.dll thedll.o thedll.in
166 # link the executable with the import library
167 ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
171 /* .idata section description
173 The .idata section is the import table. It is a collection of several
174 subsections used to keep the pieces for each dll together: .idata$[234567].
175 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
177 .idata$2 = Import Directory Table
178 = array of IMAGE_IMPORT_DESCRIPTOR's.
180 DWORD Import Lookup Table; - pointer to .idata$4
181 DWORD TimeDateStamp; - currently always 0
182 DWORD ForwarderChain; - currently always 0
183 DWORD Name; - pointer to dll's name
184 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
186 .idata$3 = null terminating entry for .idata$2.
188 .idata$4 = Import Lookup Table
189 = array of array of pointers to hint name table.
190 There is one for each dll being imported from, and each dll's set is
191 terminated by a trailing NULL.
193 .idata$5 = Import Address Table
194 = array of array of pointers to hint name table.
195 There is one for each dll being imported from, and each dll's set is
196 terminated by a trailing NULL.
197 Initially, this table is identical to the Import Lookup Table. However,
198 at load time, the loader overwrites the entries with the address of the
201 .idata$6 = Hint Name Table
202 = Array of { short, asciz } entries, one for each imported function.
203 The `short' is the function's ordinal number.
205 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)
208 /* AIX requires this to be the first thing in the file. */
215 #define show_allnames 0
217 #define PAGE_SIZE 4096
218 #define PAGE_MASK (-PAGE_SIZE)
220 #include "libiberty.h"
223 #include "demangle.h"
235 #include "coff/arm.h"
236 #include "coff/internal.h"
239 #ifdef HAVE_SYS_WAIT_H
240 #include <sys/wait.h>
241 #else /* ! HAVE_SYS_WAIT_H */
242 #if ! defined (_WIN32) || defined (__CYGWIN32__)
244 #define WIFEXITED(w) (((w)&0377) == 0)
247 #define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
250 #define WTERMSIG(w) ((w) & 0177)
253 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
255 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
257 #define WIFEXITED(w) (((w) & 0xff) == 0)
260 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
263 #define WTERMSIG(w) ((w) & 0x7f)
266 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
268 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
269 #endif /* ! HAVE_SYS_WAIT_H */
271 /* ifunc and ihead data structures: ttk@cygnus.com 1997
273 When IMPORT declarations are encountered in a .def file the
274 function import information is stored in a structure referenced by
275 the global variable IMPORT_LIST. The structure is a linked list
276 containing the names of the dll files each function is imported
277 from and a linked list of functions being imported from that dll
278 file. This roughly parallels the structure of the .idata section
279 in the PE object file.
281 The contents of .def file are interpreted from within the
282 process_def_file function. Every time an IMPORT declaration is
283 encountered, it is broken up into its component parts and passed to
284 def_import. IMPORT_LIST is initialized to NULL in function main. */
286 typedef struct ifunct
288 char *name; /* name of function being imported */
289 int ord; /* two-byte ordinal value associated with function */
293 typedef struct iheadt
295 char *dllname; /* name of dll file imported from */
296 long nfuncs; /* number of functions in list */
297 struct ifunct *funchead; /* first function in list */
298 struct ifunct *functail; /* last function in list */
299 struct iheadt *next; /* next dll file in list */
302 /* Structure containing all import information as defined in .def file
303 (qv "ihead structure"). */
305 static iheadtype *import_list = NULL;
307 static char *as_name = "as";
308 static char * as_flags = "";
310 static int no_idata4;
311 static int no_idata5;
312 static char *exp_name;
313 static char *imp_name;
314 static char *head_label;
315 static char *imp_name_lab;
316 static char *dll_name;
318 static int add_indirect = 0;
319 static int add_underscore = 0;
320 static int dontdeltemps = 0;
323 static int interwork = 0;
326 static char *def_file;
328 extern char * program_name;
333 static FILE *output_def;
334 static FILE *base_file;
337 static const char *mname = "arm";
341 static const char *mname = "i386";
345 static const char *mname = "ppc";
348 #define PATHMAX 250 /* What's the right name for this ? */
350 #define TMP_ASM "dc.s"
351 #define TMP_HEAD_S "dh.s"
352 #define TMP_HEAD_O "dh.o"
353 #define TMP_TAIL_S "dt.s"
354 #define TMP_TAIL_O "dt.o"
355 #define TMP_STUB "ds"
357 /* This bit of assemly does jmp * ....
358 s set how_jtab_roff to mark where the 32bit abs branch should go */
359 static const unsigned char i386_jtab[] =
361 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
364 static const unsigned char arm_jtab[] =
366 0x00, 0xc0, 0x9f, 0xe5,
367 0x00, 0xf0, 0x9c, 0xe5,
371 static const unsigned char thumb_jtab[] =
382 /* This is the glue sequence for PowerPC PE. There is a */
383 /* tocrel16-tocdefn reloc against the first instruction. */
384 /* We also need a IMGLUE reloc against the glue function */
385 /* to restore the toc saved by the third instruction in */
387 static const unsigned char ppc_jtab[] =
389 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
390 /* Reloc TOCREL16 __imp_xxx */
391 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
392 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
393 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
394 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
395 0x20, 0x04, 0x80, 0x4E /* bctr */
399 /* the glue instruction, picks up the toc from the stw in */
400 /* the above code: "lwz r2,4(r1)" */
401 static bfd_vma ppc_glue_insn = 0x80410004;
404 /* The outfile array must be big enough to contain a fully
405 qualified path name, plus an arbitary series of command
406 line switches. We hope that PATH_MAX times two will be
408 static char outfile [PATHMAX * 2];
413 const char *how_byte;
414 const char *how_short;
415 const char *how_long;
416 const char *how_asciz;
417 const char *how_comment;
418 const char *how_jump;
419 const char *how_global;
420 const char *how_space;
421 const char *how_align_short;
422 const char *how_align_long;
423 const char *how_bfd_target;
424 enum bfd_architecture how_bfd_arch;
425 const unsigned char *how_jtab;
426 int how_jtab_size; /* size of the jtab entry */
427 int how_jtab_roff; /* offset into it for the ind 32 reloc into idata 5 */
430 static const struct mac
435 "arm", ".byte", ".short", ".long", ".asciz", "@",
436 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
437 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
438 arm_jtab, sizeof (arm_jtab), 8
443 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386,
444 i386_jtab, sizeof (i386_jtab), 2
449 "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc,
450 ppc_jtab, sizeof (ppc_jtab), 0
455 "thumb", ".byte", ".short", ".long", ".asciz", "@",
456 "push\t{r6, r7}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tstr\tr6, [sp, #4]\n\tpop\t{r6, pc}\n\tnop",
457 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
458 thumb_jtab, sizeof (thumb_jtab), 12
471 typedef struct export
474 const char *internal_name;
484 static const char *rvaafter PARAMS ((int));
485 static const char *rvabefore PARAMS ((int));
486 static const char *asm_prefix PARAMS ((int));
487 static void append_import PARAMS ((const char *, const char *, int));
488 static void run PARAMS ((const char *, char *));
489 static void scan_open_obj_file PARAMS ((bfd *));
490 static void scan_obj_file PARAMS ((const char *));
491 static void dump_def_info PARAMS ((FILE *));
492 static int sfunc PARAMS ((const void *, const void *));
493 static void flush_page PARAMS ((FILE *, long *, int, int));
494 static void gen_def_file PARAMS ((void));
495 static void generate_idata_ofile PARAMS ((FILE *));
496 static void gen_exp_file PARAMS ((void));
497 static const char *xlate PARAMS ((const char *));
498 static void dump_iat PARAMS ((FILE *, export_type *));
499 static char *make_label PARAMS ((const char *, const char *));
500 static bfd *make_one_lib_file PARAMS ((export_type *, int));
501 static bfd *make_head PARAMS ((void));
502 static bfd *make_tail PARAMS ((void));
503 static void gen_lib_file PARAMS ((void));
504 static int pfunc PARAMS ((const void *, const void *));
505 static int nfunc PARAMS ((const void *, const void *));
506 static void remove_null_names PARAMS ((export_type **));
507 static void dtab PARAMS ((export_type **));
508 static void process_duplicates PARAMS ((export_type **));
509 static void fill_ordinals PARAMS ((export_type **));
510 static int alphafunc PARAMS ((const void *, const void *));
511 static void mangle_defs PARAMS ((void));
512 static void usage PARAMS ((int));
513 static void tell PARAMS ((const char *, va_list));
514 static void inform PARAMS ((const char *, ...));
515 static void warn PARAMS ((const char *, ...));
519 const char * message;
522 if (program_name != NULL)
523 fprintf (stderr, "%s: ", program_name);
525 vfprintf (stderr, message, args);
527 if (message [strlen (message) - 1] != '\n')
528 fputc ('\n', stderr);
534 inform (const char * message, ...)
536 inform (message, va_alist)
537 const char * message;
547 va_start (args, message);
552 tell (message, args);
559 warn (const char * message, ...)
561 warn (message, va_alist)
562 const char * message;
569 va_start (args, message);
574 tell (message, args);
591 /* xgettext:c-format */
592 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
610 /* xgettext:c-format */
611 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
630 /* xgettext:c-format */
631 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
637 #define ASM_BYTE mtable[machine].how_byte
638 #define ASM_SHORT mtable[machine].how_short
639 #define ASM_LONG mtable[machine].how_long
640 #define ASM_TEXT mtable[machine].how_asciz
641 #define ASM_C mtable[machine].how_comment
642 #define ASM_JUMP mtable[machine].how_jump
643 #define ASM_GLOBAL mtable[machine].how_global
644 #define ASM_SPACE mtable[machine].how_space
645 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
646 #define ASM_RVA_BEFORE rvabefore(machine)
647 #define ASM_RVA_AFTER rvaafter(machine)
648 #define ASM_PREFIX asm_prefix(machine)
649 #define ASM_ALIGN_LONG mtable[machine].how_align_long
650 #define HOW_BFD_TARGET 0 /* always default*/
651 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
652 #define HOW_JTAB mtable[machine].how_jtab
653 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size
654 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
658 process_def_file (name)
661 FILE *f = fopen (name, FOPEN_RT);
664 /* xgettext:c-format */
665 fatal (_("Can't open def file: %s"), name);
669 /* xgettext:c-format */
670 inform (_("Processing def file: %s"), name);
674 inform (_("Processed def file"));
677 /**********************************************************************/
679 /* Communications with the parser */
681 static const char *d_name; /* Arg to NAME or LIBRARY */
682 static int d_nfuncs; /* Number of functions exported */
683 static int d_named_nfuncs; /* Number of named functions exported */
684 static int d_low_ord; /* Lowest ordinal index */
685 static int d_high_ord; /* Highest ordinal index */
686 static export_type *d_exports; /*list of exported functions */
687 static export_type **d_exports_lexically; /* vector of exported functions in alpha order */
688 static dlist_type *d_list; /* Descriptions */
689 static dlist_type *a_list; /* Stuff to go in directives */
698 /* xgettext:c-format */
699 warn (_("Syntax error in def file %s:%d\n"), def_file, linenumber);
705 def_exports (name, internal_name, ordinal, noname, constant, data)
707 const char *internal_name;
713 struct export *p = (struct export *) xmalloc (sizeof (*p));
716 p->internal_name = internal_name ? internal_name : name;
717 p->ordinal = ordinal;
718 p->constant = constant;
727 def_name (name, base)
731 /* xgettext:c-format */
732 inform (_("NAME: %s base: %x"), name, base);
735 warn (_("Can't have LIBRARY and NAME\n"));
742 def_library (name, base)
746 /* xgettext:c-format */
747 inform (_("LIBRARY: %s base: %x"), name, base);
750 warn (_("%s: Can't have LIBRARY and NAME\n"), program_name);
757 def_description (desc)
760 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
761 d->text = xstrdup (desc);
770 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
771 d->text = xstrdup (dir);
777 def_heapsize (reserve, commit)
783 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
785 sprintf (b, "-heap 0x%x ", reserve);
786 new_directive (xstrdup (b));
790 def_stacksize (reserve, commit)
796 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
798 sprintf (b, "-stack 0x%x ", reserve);
799 new_directive (xstrdup (b));
802 /* append_import simply adds the given import definition to the global
803 import_list. It is used by def_import. */
806 append_import (symbol_name, dll_name, func_ordinal)
807 const char *symbol_name;
808 const char *dll_name;
814 for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
816 if (strcmp ((*pq)->dllname, dll_name) == 0)
819 q->functail->next = xmalloc (sizeof (ifunctype));
820 q->functail = q->functail->next;
821 q->functail->ord = func_ordinal;
822 q->functail->name = xstrdup (symbol_name);
823 q->functail->next = NULL;
829 q = xmalloc (sizeof (iheadtype));
830 q->dllname = xstrdup (dll_name);
832 q->funchead = xmalloc (sizeof (ifunctype));
833 q->functail = q->funchead;
835 q->functail->name = xstrdup (symbol_name);
836 q->functail->ord = func_ordinal;
837 q->functail->next = NULL;
842 /* def_import is called from within defparse.y when an IMPORT
843 declaration is encountered. Depending on the form of the
844 declaration, the module name may or may not need ".dll" to be
845 appended to it, the name of the function may be stored in internal
846 or entry, and there may or may not be an ordinal value associated
849 /* A note regarding the parse modes:
850 In defparse.y we have to accept import declarations which follow
851 any one of the following forms:
852 <func_name_in_app> = <dll_name>.<func_name_in_dll>
853 <func_name_in_app> = <dll_name>.<number>
854 <dll_name>.<func_name_in_dll>
856 Furthermore, the dll's name may or may not end with ".dll", which
857 complicates the parsing a little. Normally the dll's name is
858 passed to def_import() in the "module" parameter, but when it ends
859 with ".dll" it gets passed in "module" sans ".dll" and that needs
862 def_import gets five parameters:
863 APP_NAME - the name of the function in the application, if
864 present, or NULL if not present.
865 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
866 DLLEXT - the extension of the dll, if present, NULL if not present.
867 ENTRY - the name of the function in the dll, if present, or NULL.
868 ORD_VAL - the numerical tag of the function in the dll, if present,
869 or NULL. Exactly one of <entry> or <ord_val> must be
870 present (i.e., not NULL). */
873 def_import (app_name, module, dllext, entry, ord_val)
874 const char *app_name;
880 const char *application_name;
884 application_name = entry;
887 if (app_name != NULL)
888 application_name = app_name;
890 application_name = "";
895 buf = (char *) alloca (strlen (module) + strlen (dllext) + 2);
896 sprintf (buf, "%s.%s", module, dllext);
900 append_import (application_name, module, ord_val);
904 def_version (major, minor)
908 printf ("VERSION %d.%d\n", major, minor);
912 def_section (name, attr)
929 sprintf (buf, "-attr %s %s", name, atts);
930 new_directive (xstrdup (buf));
938 def_section ("CODE", attr);
945 def_section ("DATA", attr);
948 /**********************************************************************/
956 int pid, wait_status;
959 char *errmsg_fmt, *errmsg_arg;
960 char *temp_base = choose_temp_base ();
962 inform ("run: %s %s\n", what, args);
966 for (s = args; *s; s++)
970 argv = alloca (sizeof (char *) * (i + 3));
979 while (*s != ' ' && *s != 0)
987 pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
988 &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
992 inform (strerror (errno));
994 fatal (errmsg_fmt, errmsg_arg);
997 pid = pwait (pid, & wait_status, 0);
1001 /* xgettext:c-format */
1002 fatal (_("wait: %s"), strerror (errno));
1004 else if (WIFSIGNALED (wait_status))
1006 /* xgettext:c-format */
1007 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
1009 else if (WIFEXITED (wait_status))
1011 if (WEXITSTATUS (wait_status) != 0)
1012 /* xgettext:c-format */
1013 warn (_("%s exited with status %d\n"),
1014 what, WEXITSTATUS (wait_status));
1021 scan_open_obj_file (abfd)
1030 /* Look for .drectve's */
1031 s = bfd_get_section_by_name (abfd, ".drectve");
1036 size = bfd_get_section_size_before_reloc (s);
1037 buf = xmalloc (size);
1039 bfd_get_section_contents (abfd, s, buf, 0, size);
1041 /* xgettext:c-format */
1042 inform (_("Sucking in info from .drective section in %s\n"),
1043 bfd_get_filename (abfd));
1045 /* Search for -export: strings */
1051 && strncmp (p, "-export:", 8) == 0)
1058 while (p < e && *p != ' ' && *p != '-')
1060 c = xmalloc (p - name + 1);
1061 memcpy (c, name, p - name);
1063 /* FIXME: The 5th arg is for the `constant' field.
1064 What should it be? Not that it matters since it's not
1065 currently useful. */
1066 def_exports (c, 0, -1, 0, 0, 0);
1073 /* FIXME: we ought to read in and block out the base relocations */
1075 inform (_("%s: Done reading\n"));
1079 scan_obj_file (filename)
1080 const char *filename;
1082 bfd * f = bfd_openr (filename, 0);
1085 /* xgettext:c-format */
1086 fatal (_("Unable to open object file: %s"), filename);
1088 /* xgettext:c-format */
1089 inform (_("Scanning object file %s"), filename);
1091 if (bfd_check_format (f, bfd_archive))
1093 bfd *arfile = bfd_openr_next_archived_file (f, 0);
1096 if (bfd_check_format (arfile, bfd_object))
1097 scan_open_obj_file (arfile);
1099 arfile = bfd_openr_next_archived_file (f, arfile);
1102 else if (bfd_check_format (f, bfd_object))
1104 scan_open_obj_file (f);
1110 /**********************************************************************/
1118 fprintf (f, "%s ", ASM_C);
1119 for (i = 0; oav[i]; i++)
1120 fprintf (f, "%s ", oav[i]);
1122 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1124 fprintf (f, "%s %d = %s %s @ %d %s%s%s\n",
1130 exp->noname ? "NONAME " : "",
1131 exp->constant ? "CONSTANT" : "",
1132 exp->data ? "DATA" : "");
1136 /* Generate the .exp file */
1143 return *(const long *) a - *(const long *) b;
1147 flush_page (f, need, page_addr, on_page)
1155 /* Flush this page */
1156 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1160 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1162 (on_page * 2) + (on_page & 1) * 2 + 8,
1164 for (i = 0; i < on_page; i++)
1166 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (need[i] - page_addr) | 0x3000);
1170 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1179 inform (_("Adding exports to output file"));
1181 fprintf (output_def, ";");
1182 for (i = 0; oav[i]; i++)
1183 fprintf (output_def, " %s", oav[i]);
1185 fprintf (output_def, "\nEXPORTS\n");
1187 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1189 char *quote = strchr (exp->name, '.') ? "\"" : "";
1190 fprintf (output_def, "\t%s%s%s @ %d%s%s ; %s\n",
1195 exp->noname ? " NONAME" : "",
1196 exp->data ? " DATA" : "",
1197 cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS));
1200 inform (_("Added exports to output file"));
1203 /* generate_idata_ofile generates the portable assembly source code
1204 for the idata sections. It appends the source code to the end of
1208 generate_idata_ofile (filvar)
1217 if (import_list == NULL)
1220 fprintf (filvar, "%s Import data sections\n", ASM_C);
1221 fprintf (filvar, "\n\t.section\t.idata$2\n");
1222 fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1223 fprintf (filvar, "doi_idata:\n");
1226 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1228 fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1229 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
1230 ASM_C, headptr->dllname);
1231 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1232 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1233 fprintf (filvar, "\t%sdllname%d%s\n",
1234 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1235 fprintf (filvar, "\t%slisttwo%d%s\n\n",
1236 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1240 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1241 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1242 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
1243 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1244 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1246 fprintf (filvar, "\n\t.section\t.idata$4\n");
1248 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1250 fprintf (filvar, "listone%d:\n", headindex);
1251 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1252 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1253 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1254 fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1258 fprintf (filvar, "\n\t.section\t.idata$5\n");
1260 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1262 fprintf (filvar, "listtwo%d:\n", headindex);
1263 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1264 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1265 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1266 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1270 fprintf (filvar, "\n\t.section\t.idata$6\n");
1272 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1275 for (funcptr = headptr->funchead; funcptr != NULL;
1276 funcptr = funcptr->next)
1278 fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
1279 fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
1280 ((funcptr->ord) & 0xFFFF));
1281 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name);
1282 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1288 fprintf (filvar, "\n\t.section\t.idata$7\n");
1290 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1292 fprintf (filvar,"dllname%d:\n", headindex);
1293 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
1294 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1307 /* xgettext:c-format */
1308 inform (_("Generating export file: %s\n"), exp_name);
1310 f = fopen (TMP_ASM, FOPEN_WT);
1312 /* xgettext:c-format */
1313 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
1315 /* xgettext:c-format */
1316 inform (_("Opened temporary file: %s"), TMP_ASM);
1322 fprintf (f, "\t.section .edata\n\n");
1323 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
1324 fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG, (long) time(0),
1326 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
1327 fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1328 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
1331 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
1332 fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
1334 d_named_nfuncs, d_low_ord, d_high_ord);
1335 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
1336 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
1337 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1339 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
1340 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1342 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1344 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
1347 fprintf(f,"%s Export address Table\n", ASM_C);
1348 fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
1349 fprintf (f, "afuncs:\n");
1352 for (exp = d_exports; exp; exp = exp->next)
1354 if (exp->ordinal != i)
1357 fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
1359 (exp->ordinal - i) * 4,
1361 i, exp->ordinal - 1);
1364 while (i < exp->ordinal)
1366 fprintf(f,"\t%s\t0\n", ASM_LONG);
1370 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
1372 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1376 fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
1377 fprintf (f, "anames:\n");
1379 for (i = 0; (exp = d_exports_lexically[i]); i++)
1381 if (!exp->noname || show_allnames)
1382 fprintf (f, "\t%sn%d%s\n",
1383 ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
1386 fprintf (f,"%s Export Oridinal Table\n", ASM_C);
1387 fprintf (f, "anords:\n");
1388 for (i = 0; (exp = d_exports_lexically[i]); i++)
1390 if (!exp->noname || show_allnames)
1391 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
1394 fprintf(f,"%s Export Name Table\n", ASM_C);
1395 for (i = 0; (exp = d_exports_lexically[i]); i++)
1396 if (!exp->noname || show_allnames)
1397 fprintf (f, "n%d: %s \"%s\"\n",
1398 exp->ordinal, ASM_TEXT, exp->name);
1402 fprintf (f, "\t.section .drectve\n");
1403 for (dl = a_list; dl; dl = dl->next)
1405 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1410 fprintf (f, "\t.section .rdata\n");
1411 for (dl = d_list; dl; dl = dl->next)
1415 /* We dont output as ascii 'cause there can
1416 be quote characters in the string */
1419 for (p = dl->text; *p; p++)
1422 fprintf (f, "\t%s\t", ASM_BYTE);
1425 fprintf (f, "%d", *p);
1428 fprintf (f, ",0\n");
1442 /* Add to the output file a way of getting to the exported names
1443 without using the import library. */
1446 fprintf (f, "\t.section\t.rdata\n");
1447 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1448 if (!exp->noname || show_allnames)
1450 /* We use a single underscore for MS compatibility, and a
1451 double underscore for backward compatibility with old
1453 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1454 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1455 fprintf (f, "__imp_%s:\n", exp->name);
1456 fprintf (f, "_imp__%s:\n", exp->name);
1457 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1461 /* Dump the reloc section if a base file is provided */
1465 long need[PAGE_SIZE];
1472 fprintf (f, "\t.section\t.init\n");
1473 fprintf (f, "lab:\n");
1475 fseek (base_file, 0, SEEK_END);
1476 numbytes = ftell (base_file);
1477 fseek (base_file, 0, SEEK_SET);
1478 copy = xmalloc (numbytes);
1479 fread (copy, 1, numbytes, base_file);
1480 num_entries = numbytes / sizeof (long);
1483 fprintf (f, "\t.section\t.reloc\n");
1489 qsort (copy, num_entries, sizeof (long), sfunc);
1490 /* Delete duplcates */
1491 for (src = 0; src < num_entries; src++)
1493 if (last != copy[src])
1494 last = copy[dst++] = copy[src];
1498 page_addr = addr & PAGE_MASK; /* work out the page addr */
1500 for (j = 0; j < num_entries; j++)
1503 if ((addr & PAGE_MASK) != page_addr)
1505 flush_page (f, need, page_addr, on_page);
1507 page_addr = addr & PAGE_MASK;
1509 need[on_page++] = addr;
1511 flush_page (f, need, page_addr, on_page);
1513 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1517 generate_idata_ofile (f);
1521 /* assemble the file */
1522 sprintf (outfile, "%s -o %s %s", as_flags, exp_name, TMP_ASM);
1526 strcat (outfile, " -mthumb-interwork");
1529 run (as_name, outfile);
1531 if (dontdeltemps == 0)
1534 inform (_("Generated exports file"));
1543 char *copy = xmalloc (strlen (name) + 2);
1545 strcpy (copy + 1, name);
1552 p = strchr (name, '@');
1559 /**********************************************************************/
1566 if (exp->noname && !show_allnames )
1568 fprintf (f, "\t%s\t0x%08x\n",
1570 exp->ordinal | 0x80000000); /* hint or orindal ?? */
1574 fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
1590 unsigned char *data;
1605 static sinfo secdata[NSECS] =
1607 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 2},
1608 { DATA, ".data", SEC_DATA, 2},
1609 { BSS, ".bss", 0, 2},
1610 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1611 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1612 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1613 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}
1618 /* Sections numbered to make the order the same as other PowerPC NT */
1619 /* compilers. This also keeps funny alignment thingies from happening. */
1632 static sinfo secdata[NSECS] =
1634 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
1635 { PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
1636 { RDATA, ".reldata", SEC_HAS_CONTENTS, 2},
1637 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1638 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1639 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1},
1640 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1641 { DATA, ".data", SEC_DATA, 2},
1642 { BSS, ".bss", 0, 2}
1648 This is what we're trying to make. We generate the imp symbols with
1649 both single and double underscores, for compatibility.
1652 .global _GetFileVersionInfoSizeW@8
1653 .global __imp_GetFileVersionInfoSizeW@8
1654 _GetFileVersionInfoSizeW@8:
1655 jmp * __imp_GetFileVersionInfoSizeW@8
1656 .section .idata$7 # To force loading of head
1657 .long __version_a_head
1658 # Import Address Table
1660 __imp_GetFileVersionInfoSizeW@8:
1663 # Import Lookup Table
1669 .asciz "GetFileVersionInfoSizeW"
1672 For the PowerPC, here's the variation on the above scheme:
1674 # Rather than a simple "jmp *", the code to get to the dll function
1677 lwz r11,[tocv]__imp_function_name(r2)
1678 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
1687 make_label (prefix, name)
1691 int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
1692 char *copy = xmalloc (len +1 );
1693 strcpy (copy, ASM_PREFIX);
1694 strcat (copy, prefix);
1695 strcat (copy, name);
1700 make_one_lib_file (exp, i)
1708 sprintf (outfile, "%ss%d.s", prefix, i);
1709 f = fopen (outfile, FOPEN_WT);
1710 fprintf (f, "\t.text\n");
1711 fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name);
1712 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1713 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1714 fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
1715 exp->name, ASM_JUMP, exp->name);
1717 fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
1718 fprintf (f, "\t%s\t%s\n", ASM_LONG, head_label);
1721 fprintf (f,"%s Import Address Table\n", ASM_C);
1723 fprintf (f, "\t.section .idata$5\n");
1724 fprintf (f, "__imp_%s:\n", exp->name);
1725 fprintf (f, "_imp__%s:\n", exp->name);
1729 fprintf (f, "\n%s Import Lookup Table\n", ASM_C);
1730 fprintf (f, "\t.section .idata$4\n");
1734 if(!exp->noname || show_allnames)
1736 fprintf (f, "%s Hint/Name table\n", ASM_C);
1737 fprintf (f, "\t.section .idata$6\n");
1738 fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
1739 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
1744 sprintf (outfile, "%s -o %ss%d.o %ss%d.s",
1745 as_flags, prefix, i, prefix, i);
1749 strcat (outfile, " -mthumb-interwork");
1752 run (as_name, outfile);
1757 asymbol * exp_label;
1760 asymbol * iname_lab;
1761 asymbol ** iname_lab_pp;
1762 asymbol ** iname_pp;
1771 asymbol * ptrs[NSECS + 4 + EXTRA + 1];
1773 char * outname = xmalloc (10);
1777 sprintf (outname, "%s%d.o", TMP_STUB, i);
1779 abfd = bfd_openw (outname, HOW_BFD_TARGET);
1782 /* xgettext:c-format */
1783 fatal (_("bfd_open failed open stub file: %s"), outname);
1785 /* xgettext:c-format */
1786 inform (_("Creating stub file: %s"), outname);
1788 bfd_set_format (abfd, bfd_object);
1789 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
1793 bfd_set_private_flags (abfd, F_INTERWORK);
1796 /* First make symbols for the sections */
1797 for (i = 0; i < NSECS; i++)
1799 sinfo *si = secdata + i;
1802 si->sec = bfd_make_section_old_way (abfd, si->name);
1803 bfd_set_section_flags (abfd,
1807 bfd_set_section_alignment(abfd, si->sec, si->align);
1808 si->sec->output_section = si->sec;
1809 si->sym = bfd_make_empty_symbol(abfd);
1810 si->sym->name = si->sec->name;
1811 si->sym->section = si->sec;
1812 si->sym->flags = BSF_LOCAL;
1814 ptrs[oidx] = si->sym;
1815 si->sympp = ptrs + oidx;
1824 exp_label = bfd_make_empty_symbol (abfd);
1825 exp_label->name = make_label ("", exp->name);
1827 /* On PowerPC, the function name points to a descriptor in
1828 the rdata section, the first element of which is a
1829 pointer to the code (..function_name), and the second
1830 points to the .toc */
1832 if (machine == MPPC)
1833 exp_label->section = secdata[RDATA].sec;
1836 exp_label->section = secdata[TEXT].sec;
1838 exp_label->flags = BSF_GLOBAL;
1839 exp_label->value = 0;
1842 if (machine == MTHUMB)
1843 bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXT);
1845 ptrs[oidx++] = exp_label;
1848 /* Generate imp symbols with one underscore for Microsoft
1849 compatibility, and with two underscores for backward
1850 compatibility with old versions of cygwin. */
1851 iname = bfd_make_empty_symbol(abfd);
1852 iname->name = make_label ("__imp_", exp->name);
1853 iname->section = secdata[IDATA5].sec;
1854 iname->flags = BSF_GLOBAL;
1857 iname2 = bfd_make_empty_symbol(abfd);
1858 iname2->name = make_label ("_imp__", exp->name);
1859 iname2->section = secdata[IDATA5].sec;
1860 iname2->flags = BSF_GLOBAL;
1863 iname_lab = bfd_make_empty_symbol(abfd);
1865 iname_lab->name = head_label;
1866 iname_lab->section = (asection *)&bfd_und_section;
1867 iname_lab->flags = 0;
1868 iname_lab->value = 0;
1871 iname_pp = ptrs + oidx;
1872 ptrs[oidx++] = iname;
1873 ptrs[oidx++] = iname2;
1875 iname_lab_pp = ptrs + oidx;
1876 ptrs[oidx++] = iname_lab;
1879 /* The symbol refering to the code (.text) */
1881 asymbol *function_name;
1883 function_name = bfd_make_empty_symbol(abfd);
1884 function_name->name = make_label ("..", exp->name);
1885 function_name->section = secdata[TEXT].sec;
1886 function_name->flags = BSF_GLOBAL;
1887 function_name->value = 0;
1889 fn_pp = ptrs + oidx;
1890 ptrs[oidx++] = function_name;
1893 /* The .toc symbol */
1895 asymbol *toc_symbol; /* The .toc symbol */
1897 toc_symbol = bfd_make_empty_symbol (abfd);
1898 toc_symbol->name = make_label (".", "toc");
1899 toc_symbol->section = (asection *)&bfd_und_section;
1900 toc_symbol->flags = BSF_GLOBAL;
1901 toc_symbol->value = 0;
1903 toc_pp = ptrs + oidx;
1904 ptrs[oidx++] = toc_symbol;
1910 for (i = 0; i < NSECS; i++)
1912 sinfo *si = secdata + i;
1913 asection *sec = si->sec;
1922 si->size = HOW_JTAB_SIZE;
1923 si->data = xmalloc (HOW_JTAB_SIZE);
1924 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
1926 /* add the reloc into idata$5 */
1927 rel = xmalloc (sizeof (arelent));
1929 rpp = xmalloc (sizeof (arelent *) * 2);
1933 rel->address = HOW_JTAB_ROFF;
1936 if (machine == MPPC)
1938 rel->howto = bfd_reloc_type_lookup (abfd,
1939 BFD_RELOC_16_GOTOFF);
1940 rel->sym_ptr_ptr = iname_pp;
1944 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1945 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
1947 sec->orelocation = rpp;
1948 sec->reloc_count = 1;
1953 /* An idata$4 or idata$5 is one word long, and has an
1956 si->data = xmalloc (4);
1961 si->data[0] = exp->ordinal ;
1962 si->data[1] = exp->ordinal >> 8;
1963 si->data[2] = exp->ordinal >> 16;
1968 sec->reloc_count = 1;
1969 memset (si->data, 0, si->size);
1970 rel = xmalloc (sizeof (arelent));
1971 rpp = xmalloc (sizeof (arelent *) * 2);
1976 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
1977 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
1978 sec->orelocation = rpp;
1986 /* This used to add 1 to exp->hint. I don't know
1987 why it did that, and it does not match what I see
1988 in programs compiled with the MS tools. */
1989 int idx = exp->hint;
1990 si->size = strlen (xlate (exp->name)) + 3;
1991 si->data = xmalloc (si->size);
1992 si->data[0] = idx & 0xff;
1993 si->data[1] = idx >> 8;
1994 strcpy (si->data + 2, xlate (exp->name));
1999 si->data =xmalloc(4);
2000 memset (si->data, 0, si->size);
2001 rel = xmalloc (sizeof (arelent));
2002 rpp = xmalloc (sizeof (arelent *) * 2);
2006 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2007 rel->sym_ptr_ptr = iname_lab_pp;
2008 sec->orelocation = rpp;
2009 sec->reloc_count = 1;
2015 /* The .pdata section is 5 words long. */
2016 /* Think of it as: */
2019 /* bfd_vma BeginAddress, [0x00] */
2020 /* EndAddress, [0x04] */
2021 /* ExceptionHandler, [0x08] */
2022 /* HandlerData, [0x0c] */
2023 /* PrologEndAddress; [0x10] */
2026 /* So this pdata section setups up this as a glue linkage to
2027 a dll routine. There are a number of house keeping things
2030 1. In the name of glue trickery, the ADDR32 relocs for 0,
2031 4, and 0x10 are set to point to the same place:
2033 2. There is one more reloc needed in the pdata section.
2034 The actual glue instruction to restore the toc on
2035 return is saved as the offset in an IMGLUE reloc.
2036 So we need a total of four relocs for this section.
2038 3. Lastly, the HandlerData field is set to 0x03, to indicate
2039 that this is a glue routine.
2041 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
2043 /* alignment must be set to 2**2 or you get extra stuff */
2044 bfd_set_section_alignment(abfd, sec, 2);
2047 si->data =xmalloc(4 * 5);
2048 memset (si->data, 0, si->size);
2049 rpp = xmalloc (sizeof (arelent *) * 5);
2050 rpp[0] = imglue = xmalloc (sizeof (arelent));
2051 rpp[1] = ba_rel = xmalloc (sizeof (arelent));
2052 rpp[2] = ea_rel = xmalloc (sizeof (arelent));
2053 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
2056 /* stick the toc reload instruction in the glue reloc */
2057 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
2060 imglue->howto = bfd_reloc_type_lookup (abfd,
2061 BFD_RELOC_32_GOTOFF);
2062 imglue->sym_ptr_ptr = fn_pp;
2064 ba_rel->address = 0;
2066 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2067 ba_rel->sym_ptr_ptr = fn_pp;
2069 bfd_put_32(abfd, 0x18, si->data + 0x04);
2070 ea_rel->address = 4;
2072 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2073 ea_rel->sym_ptr_ptr = fn_pp;
2075 /* mark it as glue */
2076 bfd_put_32(abfd, 0x03, si->data + 0x0c);
2078 /* mark the prolog end address */
2079 bfd_put_32(abfd, 0x0D, si->data + 0x10);
2080 pea_rel->address = 0x10;
2081 pea_rel->addend = 0;
2082 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2083 pea_rel->sym_ptr_ptr = fn_pp;
2085 sec->orelocation = rpp;
2086 sec->reloc_count = 4;
2090 /* Each external function in a PowerPC PE file has a two word
2091 descriptor consisting of:
2092 1. The address of the code.
2093 2. The address of the appropriate .toc
2094 We use relocs to build this.
2098 si->data = xmalloc (8);
2099 memset (si->data, 0, si->size);
2101 rpp = xmalloc (sizeof (arelent *) * 3);
2102 rpp[0] = rel = xmalloc (sizeof (arelent));
2103 rpp[1] = xmalloc (sizeof (arelent));
2108 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2109 rel->sym_ptr_ptr = fn_pp;
2115 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2116 rel->sym_ptr_ptr = toc_pp;
2118 sec->orelocation = rpp;
2119 sec->reloc_count = 2;
2121 #endif /* DLLTOOL_PPC */
2127 /* Size up all the sections */
2128 for (i = 0; i < NSECS; i++)
2130 sinfo *si = secdata + i;
2132 bfd_set_section_size (abfd, si->sec, si->size);
2133 bfd_set_section_vma (abfd, si->sec, vma);
2135 /* vma += si->size;*/
2138 /* Write them out */
2139 for (i = 0; i < NSECS; i++)
2141 sinfo *si = secdata + i;
2143 if (i == IDATA5 && no_idata5)
2146 if (i == IDATA4 && no_idata4)
2149 bfd_set_section_contents (abfd, si->sec,
2154 bfd_set_symtab (abfd, ptrs, oidx);
2156 abfd = bfd_openr (outname, HOW_BFD_TARGET);
2165 FILE * f = fopen (TMP_HEAD_S, FOPEN_WT);
2167 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2168 fprintf (f, "\t.section .idata$2\n");
2170 fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
2172 fprintf (f, "%s:\n", head_label);
2174 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2175 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2177 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2178 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2179 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2180 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2181 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2186 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2188 ASM_RVA_AFTER, ASM_C);
2190 fprintf (f, "%sStuff for compatibility\n", ASM_C);
2194 fprintf (f, "\t.section\t.idata$5\n");
2195 fprintf (f, "\t%s\t0\n", ASM_LONG);
2196 fprintf (f, "fthunk:\n");
2200 fprintf (f, "\t.section\t.idata$4\n");
2202 fprintf (f, "\t%s\t0\n", ASM_LONG);
2203 fprintf (f, "\t.section .idata$4\n");
2204 fprintf (f, "hname:\n");
2208 sprintf (outfile, "%s -o %s %s", as_flags, TMP_HEAD_O, TMP_HEAD_S);
2212 strcat (outfile, " -mthumb-interwork");
2215 run (as_name, outfile);
2217 return bfd_openr (TMP_HEAD_O, HOW_BFD_TARGET);
2223 FILE * f = fopen (TMP_TAIL_S, FOPEN_WT);
2227 fprintf (f, "\t.section .idata$4\n");
2228 fprintf (f, "\t%s\t0\n", ASM_LONG);
2232 fprintf (f, "\t.section .idata$5\n");
2233 fprintf (f, "\t%s\t0\n", ASM_LONG);
2237 /* Normally, we need to see a null descriptor built in idata$3 to
2238 act as the terminator for the list. The ideal way, I suppose,
2239 would be to mark this section as a comdat type 2 section, so
2240 only one would appear in the final .exe (if our linker supported
2241 comdat, that is) or cause it to be inserted by something else (say
2245 fprintf (f, "\t.section .idata$3\n");
2246 fprintf (f, "\t%s\t0\n", ASM_LONG);
2247 fprintf (f, "\t%s\t0\n", ASM_LONG);
2248 fprintf (f, "\t%s\t0\n", ASM_LONG);
2249 fprintf (f, "\t%s\t0\n", ASM_LONG);
2250 fprintf (f, "\t%s\t0\n", ASM_LONG);
2254 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2255 do too. Original, huh? */
2256 fprintf (f, "\t.section .idata$6\n");
2258 fprintf (f, "\t.section .idata$7\n");
2261 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
2262 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
2263 imp_name_lab, ASM_TEXT, dll_name);
2267 sprintf (outfile, "%s -o %s %s", as_flags, TMP_TAIL_O, TMP_TAIL_S);
2271 strcat (outfile, " -mthumb-interwork");
2274 run (as_name, outfile);
2276 return bfd_openr (TMP_TAIL_O, HOW_BFD_TARGET);
2291 outarch = bfd_openw (imp_name, HOW_BFD_TARGET);
2294 /* xgettext:c-format */
2295 fatal (_("Can't open .lib file: %s"), imp_name);
2297 /* xgettext:c-format */
2298 inform (_("Creating library file: %s\n"), imp_name);
2300 bfd_set_format (outarch, bfd_archive);
2301 outarch->has_armap = 1;
2303 /* Work out a reasonable size of things to put onto one line. */
2305 ar_head = make_head ();
2306 ar_tail = make_tail();
2308 if (ar_head == NULL || ar_tail == NULL)
2311 for (i = 0; (exp = d_exports_lexically[i]); i++)
2313 bfd *n = make_one_lib_file (exp, i);
2318 /* Now stick them all into the archive */
2320 ar_head->next = head;
2321 ar_tail->next = ar_head;
2324 if (! bfd_set_archive_head (outarch, head))
2325 bfd_fatal ("bfd_set_archive_head");
2327 if (! bfd_close (outarch))
2328 bfd_fatal (imp_name);
2330 while (head != NULL)
2332 bfd *n = head->next;
2337 /* Delete all the temp files */
2339 if (dontdeltemps == 0)
2341 unlink (TMP_HEAD_O);
2342 unlink (TMP_HEAD_S);
2343 unlink (TMP_TAIL_O);
2344 unlink (TMP_TAIL_S);
2347 if (dontdeltemps < 2)
2349 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2351 sprintf (outfile, "%s%d.o", TMP_STUB, i);
2352 if (unlink (outfile) < 0)
2353 /* xgettext:c-format */
2354 warn (_("cannot delete %s: %s\n"), outfile, strerror (errno));
2358 inform (_("Created lib file"));
2361 /**********************************************************************/
2363 /* Run through the information gathered from the .o files and the
2364 .def file and work out the best stuff */
2370 export_type *ap = *(export_type **) a;
2371 export_type *bp = *(export_type **) b;
2372 if (ap->ordinal == bp->ordinal)
2375 /* unset ordinals go to the bottom */
2376 if (ap->ordinal == -1)
2378 if (bp->ordinal == -1)
2380 return (ap->ordinal - bp->ordinal);
2388 export_type *ap = *(export_type **) a;
2389 export_type *bp = *(export_type **) b;
2391 return (strcmp (ap->name, bp->name));
2395 remove_null_names (ptr)
2400 for (dst = src = 0; src < d_nfuncs; src++)
2404 ptr[dst] = ptr[src];
2417 for (i = 0; i < d_nfuncs; i++)
2421 printf ("%d %s @ %d %s%s%s\n",
2422 i, ptr[i]->name, ptr[i]->ordinal,
2423 ptr[i]->noname ? "NONAME " : "",
2424 ptr[i]->constant ? "CONSTANT" : "",
2425 ptr[i]->data ? "DATA" : "");
2434 process_duplicates (d_export_vec)
2435 export_type **d_export_vec;
2443 /* Remove duplicates */
2444 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
2446 dtab (d_export_vec);
2447 for (i = 0; i < d_nfuncs - 1; i++)
2449 if (strcmp (d_export_vec[i]->name,
2450 d_export_vec[i + 1]->name) == 0)
2453 export_type *a = d_export_vec[i];
2454 export_type *b = d_export_vec[i + 1];
2458 /* xgettext:c-format */
2459 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2460 a->name, a->ordinal, b->ordinal);
2462 if (a->ordinal != -1
2463 && b->ordinal != -1)
2464 /* xgettext:c-format */
2465 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2468 /* Merge attributes */
2469 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
2470 b->constant |= a->constant;
2471 b->noname |= a->noname;
2473 d_export_vec[i] = 0;
2476 dtab (d_export_vec);
2477 remove_null_names (d_export_vec);
2478 dtab (d_export_vec);
2483 /* Count the names */
2484 for (i = 0; i < d_nfuncs; i++)
2486 if (!d_export_vec[i]->noname)
2492 fill_ordinals (d_export_vec)
2493 export_type **d_export_vec;
2500 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2502 /* fill in the unset ordinals with ones from our range */
2504 ptr = (char *) xmalloc (size);
2506 memset (ptr, 0, size);
2508 /* Mark in our large vector all the numbers that are taken */
2509 for (i = 0; i < d_nfuncs; i++)
2511 if (d_export_vec[i]->ordinal != -1)
2513 ptr[d_export_vec[i]->ordinal] = 1;
2514 if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
2516 lowest = d_export_vec[i]->ordinal;
2521 /* Start at 1 for compatibility with MS toolchain. */
2525 /* Now fill in ordinals where the user wants us to choose. */
2526 for (i = 0; i < d_nfuncs; i++)
2528 if (d_export_vec[i]->ordinal == -1)
2532 /* First try within or after any user supplied range. */
2533 for (j = lowest; j < size; j++)
2537 d_export_vec[i]->ordinal = j;
2541 /* Then try before the range. */
2542 for (j = lowest; j >0; j--)
2546 d_export_vec[i]->ordinal = j;
2557 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2559 /* Work out the lowest and highest ordinal numbers. */
2562 if (d_export_vec[0])
2563 d_low_ord = d_export_vec[0]->ordinal;
2564 if (d_export_vec[d_nfuncs-1])
2565 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
2574 const export_type **a = (const export_type **) av;
2575 const export_type **b = (const export_type **) bv;
2577 return strcmp ((*a)->name, (*b)->name);
2583 /* First work out the minimum ordinal chosen */
2589 export_type **d_export_vec
2590 = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
2592 inform (_("Processing definitions"));
2594 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2596 d_export_vec[i] = exp;
2599 process_duplicates (d_export_vec);
2600 fill_ordinals (d_export_vec);
2602 /* Put back the list in the new order */
2604 for (i = d_nfuncs - 1; i >= 0; i--)
2606 d_export_vec[i]->next = d_exports;
2607 d_exports = d_export_vec[i];
2610 /* Build list in alpha order */
2611 d_exports_lexically = (export_type **)
2612 xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
2614 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2616 d_exports_lexically[i] = exp;
2618 d_exports_lexically[i] = 0;
2620 qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
2622 /* Fill exp entries with their hint values */
2624 for (i = 0; i < d_nfuncs; i++)
2626 if (!d_exports_lexically[i]->noname || show_allnames)
2627 d_exports_lexically[i]->hint = hint++;
2630 inform (_("Processed definitions"));
2633 /**********************************************************************/
2639 /* xgetext:c-format */
2640 fprintf (stderr, _("Usage %s <options> <object-files>\n"), program_name);
2641 /* xgetext:c-format */
2642 fprintf (stderr, _(" -m --machine <machine> Create {arm, i386, ppc, thumb} DLL. [default: %s]\n"), mname);
2643 fprintf (stderr, _(" -e --output-exp <outname> Generate an export file.\n"));
2644 fprintf (stderr, _(" -l --output-lib <outname> Generate an interface library.\n"));
2645 fprintf (stderr, _(" -a --add-indirect Add dll indirects to export file.\n"));
2646 fprintf (stderr, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
2647 fprintf (stderr, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
2648 fprintf (stderr, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
2649 fprintf (stderr, _(" -b --base-file <basefile> Read linker generated base file.\n"));
2650 fprintf (stderr, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
2651 fprintf (stderr, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
2652 fprintf (stderr, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
2653 fprintf (stderr, _(" -k --kill-at Kill @<n> from exported names.\n"));
2654 fprintf (stderr, _(" -S --as <name> Use <name> for assembler.\n"));
2655 fprintf (stderr, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
2657 fprintf (stderr, _(" -i --interwork Support ARM/Thumb interworking.\n"));
2659 fprintf (stderr, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
2660 fprintf (stderr, _(" -v --verbose Be verbose.\n"));
2661 fprintf (stderr, _(" -V --version Display the program version.\n"));
2662 fprintf (stderr, _(" -h --help Display this information.\n"));
2667 #define OPTION_NO_IDATA4 'x'
2668 #define OPTION_NO_IDATA5 'c'
2669 static const struct option long_options[] =
2671 {"no-delete", no_argument, NULL, 'n'},
2672 {"dllname", required_argument, NULL, 'D'},
2673 {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
2674 {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
2675 {"output-exp", required_argument, NULL, 'e'},
2676 {"output-def", required_argument, NULL, 'z'},
2677 {"output-lib", required_argument, NULL, 'l'},
2678 {"def", required_argument, NULL, 'd'}, /* for compatiblity with older versions */
2679 {"input-def", required_argument, NULL, 'd'},
2680 {"add-underscore", no_argument, NULL, 'U'},
2681 {"kill-at", no_argument, NULL, 'k'},
2682 {"verbose", no_argument, NULL, 'v'},
2683 {"version", no_argument, NULL, 'V'},
2684 {"help", no_argument, NULL, 'h'},
2685 {"machine", required_argument, NULL, 'm'},
2686 {"add-indirect", no_argument, NULL, 'a'},
2687 {"base-file", required_argument, NULL, 'b'},
2688 {"as", required_argument, NULL, 'S'},
2689 {"as-flags", required_argument, NULL, 'f'},
2691 {"interwork", no_argument, NULL, 'i'},
2704 program_name = av[0];
2707 #ifdef HAVE_SETLOCALE
2708 setlocale (LC_MESSAGES, "");
2710 bindtextdomain (PACKAGE, LOCALEDIR);
2711 textdomain (PACKAGE);
2713 while ((c = getopt_long (ac, av, "xcz:S:aD:l:e:nkvVb:Uh?m:d:f:i",
2719 case OPTION_NO_IDATA4:
2722 case OPTION_NO_IDATA5:
2732 /* ignored for compatibility */
2739 output_def = fopen (optarg, FOPEN_WT);
2761 print_version (program_name);
2770 /* We don't currently define YYDEBUG when building
2788 base_file = fopen (optarg, FOPEN_RB);
2791 /* xgettext:c-format */
2792 fatal (_("Unable to open base-file: %s"), optarg);
2800 for (i = 0; mtable[i].type; i++)
2802 if (strcmp (mtable[i].type, mname) == 0)
2806 if (!mtable[i].type)
2807 /* xgettext:c-format */
2808 fatal (_("Machine '%s' not supported"), mname);
2813 /* Always enable interworking for Thumb targets. */
2814 if (machine == MTHUMB && (! interwork))
2818 if (!dll_name && exp_name)
2820 int len = strlen (exp_name) + 5;
2821 dll_name = xmalloc (len);
2822 strcpy (dll_name, exp_name);
2823 strcat (dll_name, ".dll");
2827 process_def_file (def_file);
2832 firstarg = av[optind];
2833 scan_obj_file (av[optind]);
2844 /* Make imp_name safe for use as a label. */
2847 imp_name_lab = xstrdup (imp_name);
2848 for (p = imp_name_lab; *p; p++)
2850 if (!isalpha ((unsigned char) *p) && !isdigit ((unsigned char) *p))
2853 head_label = make_label("_head_", imp_name_lab);