* ld-cris/got7.s, ld-cris/init.s, ld-cris/pic-gc-72.d,
[deliverable/binutils-gdb.git] / binutils / dlltool.c
CommitLineData
252b5132 1/* dlltool.c -- tool to generate stuff for PE style DLLs
9210d879 2 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
fd64a958 3 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
252b5132
RH
4
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
32866df7 9 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
b43b5d5f
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
252b5132
RH
21
22
c9e38879 23/* This program allows you to build the files necessary to create
252b5132
RH
24 DLLs to run on a system which understands PE format image files.
25 (eg, Windows NT)
26
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.
31
32 A DLL contains an export table which contains the information
33 which the runtime loader needs to tie up references from a
34 referencing program.
35
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.
40
41 A DEF file contains any number of the following commands:
42
43
44 NAME <name> [ , <base> ]
45 The result is going to be <name>.EXE
46
47 LIBRARY <name> [ , <base> ]
48 The result is going to be <name>.DLL
49
04847a4d
CF
50 EXPORTS ( ( ( <name1> [ = <name2> ] )
51 | ( <name1> = <module-name> . <external-name>))
7aa52b1f 52 [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] [PRIVATE] ) *
252b5132 53 Declares name1 as an exported symbol from the
04847a4d
CF
54 DLL, with optional ordinal number <integer>.
55 Or declares name1 as an alias (forward) of the function <external-name>
56 in the DLL <module-name>.
252b5132
RH
57
58 IMPORTS ( ( <internal-name> = <module-name> . <integer> )
59 | ( [ <internal-name> = ] <module-name> . <external-name> )) *
c7de9216 60 Declares that <external-name> or the exported function whose ordinal number
252b5132
RH
61 is <integer> is to be imported from the file <module-name>. If
62 <internal-name> is specified then this is the name that the imported
50c2245b 63 function will be refereed to in the body of the DLL.
252b5132
RH
64
65 DESCRIPTION <string>
66 Puts <string> into output .exp file in the .rdata section
67
68 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
69 Generates --stack|--heap <number-reserve>,<number-commit>
70 in the output .drectve section. The linker will
71 see this and act upon it.
72
73 [CODE|DATA] <attr>+
74 SECTIONS ( <sectionname> <attr>+ )*
75 <attr> = READ | WRITE | EXECUTE | SHARED
76 Generates --attr <sectionname> <attr> in the output
77 .drectve section. The linker will see this and act
78 upon it.
79
80
81 A -export:<name> in a .drectve section in an input .o or .a
82 file to this program is equivalent to a EXPORTS <name>
83 in a .DEF file.
84
85
86
87 The program generates output files with the prefix supplied
88 on the command line, or in the def file, or taken from the first
89 supplied argument.
90
91 The .exp.s file contains the information necessary to export
92 the routines in the DLL. The .lib.s file contains the information
93 necessary to use the DLL's routines from a referencing program.
94
95
96
97 Example:
98
99 file1.c:
100 asm (".section .drectve");
101 asm (".ascii \"-export:adef\"");
102
103 void adef (char * s)
104 {
105 printf ("hello from the dll %s\n", s);
106 }
107
108 void bdef (char * s)
109 {
110 printf ("hello from the dll and the other entry point %s\n", s);
111 }
112
113 file2.c:
114 asm (".section .drectve");
115 asm (".ascii \"-export:cdef\"");
116 asm (".ascii \"-export:ddef\"");
26044998 117
252b5132
RH
118 void cdef (char * s)
119 {
120 printf ("hello from the dll %s\n", s);
121 }
122
123 void ddef (char * s)
124 {
125 printf ("hello from the dll and the other entry point %s\n", s);
126 }
127
661016bb 128 int printf (void)
252b5132
RH
129 {
130 return 9;
131 }
132
661016bb
NC
133 themain.c:
134 int main (void)
252b5132 135 {
661016bb
NC
136 cdef ();
137 return 0;
252b5132
RH
138 }
139
140 thedll.def
141
142 LIBRARY thedll
143 HEAPSIZE 0x40000, 0x2000
144 EXPORTS bdef @ 20
145 cdef @ 30 NONAME
146
147 SECTIONS donkey READ WRITE
148 aardvark EXECUTE
149
6e7d8205 150 # Compile up the parts of the dll and the program
252b5132 151
6e7d8205 152 gcc -c file1.c file2.c themain.c
252b5132 153
6e7d8205
NC
154 # Optional: put the dll objects into a library
155 # (you don't have to, you could name all the object
156 # files on the dlltool line)
252b5132
RH
157
158 ar qcv thedll.in file1.o file2.o
159 ranlib thedll.in
160
6e7d8205
NC
161 # Run this tool over the DLL's .def file and generate an exports
162 # file (thedll.o) and an imports file (thedll.a).
163 # (You may have to use -S to tell dlltool where to find the assembler).
26044998 164
aff05906 165 dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
252b5132 166
aff05906 167 # Build the dll with the library and the export table
26044998 168
252b5132
RH
169 ld -o thedll.dll thedll.o thedll.in
170
6e7d8205 171 # Link the executable with the import library
26044998 172
661016bb 173 gcc -o themain.exe themain.o thedll.a
252b5132 174
aff05906
NC
175 This example can be extended if relocations are needed in the DLL:
176
177 # Compile up the parts of the dll and the program
178
179 gcc -c file1.c file2.c themain.c
180
181 # Run this tool over the DLL's .def file and generate an imports file.
26044998 182
aff05906
NC
183 dlltool --def thedll.def --output-lib thedll.lib
184
185 # Link the executable with the import library and generate a base file
186 # at the same time
26044998 187
aff05906
NC
188 gcc -o themain.exe themain.o thedll.lib -Wl,--base-file -Wl,themain.base
189
190 # Run this tool over the DLL's .def file and generate an exports file
191 # which includes the relocations from the base file.
26044998 192
aff05906
NC
193 dlltool --def thedll.def --base-file themain.base --output-exp thedll.exp
194
195 # Build the dll with file1.o, file2.o and the export table
26044998 196
c9e38879 197 ld -o thedll.dll thedll.exp file1.o file2.o */
252b5132
RH
198
199/* .idata section description
200
201 The .idata section is the import table. It is a collection of several
202 subsections used to keep the pieces for each dll together: .idata$[234567].
203 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
204
205 .idata$2 = Import Directory Table
206 = array of IMAGE_IMPORT_DESCRIPTOR's.
207
208 DWORD Import Lookup Table; - pointer to .idata$4
209 DWORD TimeDateStamp; - currently always 0
210 DWORD ForwarderChain; - currently always 0
211 DWORD Name; - pointer to dll's name
212 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
213
214 .idata$3 = null terminating entry for .idata$2.
215
216 .idata$4 = Import Lookup Table
217 = array of array of pointers to hint name table.
218 There is one for each dll being imported from, and each dll's set is
219 terminated by a trailing NULL.
220
221 .idata$5 = Import Address Table
222 = array of array of pointers to hint name table.
223 There is one for each dll being imported from, and each dll's set is
224 terminated by a trailing NULL.
225 Initially, this table is identical to the Import Lookup Table. However,
226 at load time, the loader overwrites the entries with the address of the
227 function.
228
229 .idata$6 = Hint Name Table
230 = Array of { short, asciz } entries, one for each imported function.
231 The `short' is the function's ordinal number.
232
c9e38879 233 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc). */
252b5132
RH
234
235/* AIX requires this to be the first thing in the file. */
236#ifndef __GNUC__
237# ifdef _AIX
238 #pragma alloca
239#endif
240#endif
241
242#define show_allnames 0
243
d078078d
KT
244#define PAGE_SIZE ((bfd_vma) 4096)
245#define PAGE_MASK ((bfd_vma) (-4096))
3db64b00 246#include "sysdep.h"
252b5132
RH
247#include "bfd.h"
248#include "libiberty.h"
252b5132
RH
249#include "getopt.h"
250#include "demangle.h"
bb0cb4db 251#include "dyn-string.h"
3db64b00 252#include "bucomm.h"
252b5132 253#include "dlltool.h"
3882b010 254#include "safe-ctype.h"
252b5132 255
252b5132 256#include <time.h>
bb0cb4db 257#include <sys/stat.h>
252b5132 258#include <stdarg.h>
0fd555c4
NC
259#include <assert.h>
260
252b5132
RH
261#ifdef DLLTOOL_ARM
262#include "coff/arm.h"
263#include "coff/internal.h"
264#endif
99ad8390
NC
265#ifdef DLLTOOL_MX86_64
266#include "coff/x86_64.h"
267#endif
252b5132 268
49e315b1 269/* Forward references. */
2da42df6
AJ
270static char *look_for_prog (const char *, const char *, int);
271static char *deduce_name (const char *);
49e315b1
NC
272
273#ifdef DLLTOOL_MCORE_ELF
fd64a958 274static void mcore_elf_cache_filename (const char *);
2da42df6 275static void mcore_elf_gen_out_file (void);
49e315b1 276#endif
26044998 277
252b5132
RH
278#ifdef HAVE_SYS_WAIT_H
279#include <sys/wait.h>
280#else /* ! HAVE_SYS_WAIT_H */
281#if ! defined (_WIN32) || defined (__CYGWIN32__)
282#ifndef WIFEXITED
c9e38879 283#define WIFEXITED(w) (((w) & 0377) == 0)
252b5132
RH
284#endif
285#ifndef WIFSIGNALED
c9e38879 286#define WIFSIGNALED(w) (((w) & 0377) != 0177 && ((w) & ~0377) == 0)
252b5132
RH
287#endif
288#ifndef WTERMSIG
289#define WTERMSIG(w) ((w) & 0177)
290#endif
291#ifndef WEXITSTATUS
292#define WEXITSTATUS(w) (((w) >> 8) & 0377)
293#endif
294#else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
295#ifndef WIFEXITED
296#define WIFEXITED(w) (((w) & 0xff) == 0)
297#endif
298#ifndef WIFSIGNALED
299#define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
300#endif
301#ifndef WTERMSIG
302#define WTERMSIG(w) ((w) & 0x7f)
303#endif
304#ifndef WEXITSTATUS
305#define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
306#endif
307#endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
308#endif /* ! HAVE_SYS_WAIT_H */
309
310/* ifunc and ihead data structures: ttk@cygnus.com 1997
311
312 When IMPORT declarations are encountered in a .def file the
313 function import information is stored in a structure referenced by
314 the global variable IMPORT_LIST. The structure is a linked list
315 containing the names of the dll files each function is imported
316 from and a linked list of functions being imported from that dll
317 file. This roughly parallels the structure of the .idata section
318 in the PE object file.
319
320 The contents of .def file are interpreted from within the
321 process_def_file function. Every time an IMPORT declaration is
322 encountered, it is broken up into its component parts and passed to
323 def_import. IMPORT_LIST is initialized to NULL in function main. */
324
325typedef struct ifunct
326{
c9e38879
NC
327 char * name; /* Name of function being imported. */
328 int ord; /* Two-byte ordinal value associated with function. */
252b5132
RH
329 struct ifunct *next;
330} ifunctype;
331
332typedef struct iheadt
333{
c9e38879
NC
334 char *dllname; /* Name of dll file imported from. */
335 long nfuncs; /* Number of functions in list. */
336 struct ifunct *funchead; /* First function in list. */
337 struct ifunct *functail; /* Last function in list. */
338 struct iheadt *next; /* Next dll file in list. */
252b5132
RH
339} iheadtype;
340
341/* Structure containing all import information as defined in .def file
342 (qv "ihead structure"). */
343
344static iheadtype *import_list = NULL;
345
49e315b1 346static char *as_name = NULL;
252b5132
RH
347static char * as_flags = "";
348
bf7a6389 349static char *tmp_prefix;
0e11a9e9 350
252b5132
RH
351static int no_idata4;
352static int no_idata5;
353static char *exp_name;
354static char *imp_name;
d4732f7c
CW
355static char *identify_imp_name;
356static char *identify_dll_name;
252b5132
RH
357static char *head_label;
358static char *imp_name_lab;
359static char *dll_name;
360
361static int add_indirect = 0;
362static int add_underscore = 0;
14288fdc 363static int add_stdcall_underscore = 0;
252b5132
RH
364static int dontdeltemps = 0;
365
b34976b6 366/* TRUE if we should export all symbols. Otherwise, we only export
252b5132 367 symbols listed in .drectve sections or in the def file. */
b34976b6 368static bfd_boolean export_all_symbols;
252b5132 369
b34976b6 370/* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when
252b5132 371 exporting all symbols. */
b34976b6 372static bfd_boolean do_default_excludes = TRUE;
252b5132
RH
373
374/* Default symbols to exclude when exporting all the symbols. */
375static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";
376
b34976b6 377/* TRUE if we should add __imp_<SYMBOL> to import libraries for backward
5f0f29c3 378 compatibility to old Cygwin releases. */
b34976b6 379static bfd_boolean create_compat_implib;
5f0f29c3 380
252b5132
RH
381static char *def_file;
382
383extern char * program_name;
384
385static int machine;
386static int killat;
387static int add_stdcall_alias;
607dea97 388static const char *ext_prefix_alias;
252b5132
RH
389static int verbose;
390static FILE *output_def;
391static FILE *base_file;
392
7aad4c3d 393#ifdef DLLTOOL_DEFAULT_ARM
252b5132
RH
394static const char *mname = "arm";
395#endif
7aad4c3d
L
396
397#ifdef DLLTOOL_DEFAULT_ARM_EPOC
398static const char *mname = "arm-epoc";
399#endif
400
401#ifdef DLLTOOL_DEFAULT_ARM_WINCE
402static const char *mname = "arm-wince";
a8c548cb 403#endif
252b5132 404
7aad4c3d 405#ifdef DLLTOOL_DEFAULT_I386
252b5132
RH
406static const char *mname = "i386";
407#endif
408
7aad4c3d 409#ifdef DLLTOOL_DEFAULT_MX86_64
99ad8390
NC
410static const char *mname = "i386:x86-64";
411#endif
412
7aad4c3d 413#ifdef DLLTOOL_DEFAULT_PPC
252b5132
RH
414static const char *mname = "ppc";
415#endif
416
7aad4c3d 417#ifdef DLLTOOL_DEFAULT_SH
8a0e0f38
NC
418static const char *mname = "sh";
419#endif
420
7aad4c3d 421#ifdef DLLTOOL_DEFAULT_MIPS
8a0e0f38
NC
422static const char *mname = "mips";
423#endif
424
7aad4c3d 425#ifdef DLLTOOL_DEFAULT_MCORE
7e301c9c 426static const char * mname = "mcore-le";
661016bb
NC
427#endif
428
7aad4c3d 429#ifdef DLLTOOL_DEFAULT_MCORE_ELF
661016bb 430static const char * mname = "mcore-elf";
49e315b1
NC
431static char * mcore_elf_out_file = NULL;
432static char * mcore_elf_linker = NULL;
433static char * mcore_elf_linker_flags = NULL;
434
661016bb
NC
435#define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
436#endif
437
438#ifndef DRECTVE_SECTION_NAME
439#define DRECTVE_SECTION_NAME ".drectve"
440#endif
441
0fd555c4
NC
442/* What's the right name for this ? */
443#define PATHMAX 250
444
445/* External name alias numbering starts here. */
446#define PREFIX_ALIAS_BASE 20000
252b5132 447
0e11a9e9
CF
448char *tmp_asm_buf;
449char *tmp_head_s_buf;
450char *tmp_head_o_buf;
451char *tmp_tail_s_buf;
452char *tmp_tail_o_buf;
453char *tmp_stub_buf;
454
bf7a6389
CF
455#define TMP_ASM dlltmp (&tmp_asm_buf, "%sc.s")
456#define TMP_HEAD_S dlltmp (&tmp_head_s_buf, "%sh.s")
457#define TMP_HEAD_O dlltmp (&tmp_head_o_buf, "%sh.o")
458#define TMP_TAIL_S dlltmp (&tmp_tail_s_buf, "%st.s")
459#define TMP_TAIL_O dlltmp (&tmp_tail_o_buf, "%st.o")
460#define TMP_STUB dlltmp (&tmp_stub_buf, "%ss")
252b5132 461
50c2245b 462/* This bit of assembly does jmp * .... */
252b5132
RH
463static const unsigned char i386_jtab[] =
464{
465 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
466};
467
468static const unsigned char arm_jtab[] =
469{
b890a735
CM
470 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
471 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
472 0, 0, 0, 0
473};
474
475static const unsigned char arm_interwork_jtab[] =
476{
477 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
478 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */
479 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */
252b5132
RH
480 0, 0, 0, 0
481};
482
483static const unsigned char thumb_jtab[] =
484{
b890a735
CM
485 0x40, 0xb4, /* push {r6} */
486 0x02, 0x4e, /* ldr r6, [pc, #8] */
487 0x36, 0x68, /* ldr r6, [r6] */
488 0xb4, 0x46, /* mov ip, r6 */
489 0x40, 0xbc, /* pop {r6} */
490 0x60, 0x47, /* bx ip */
252b5132
RH
491 0, 0, 0, 0
492};
493
661016bb
NC
494static const unsigned char mcore_be_jtab[] =
495{
ba8c44fc 496 0x71, 0x02, /* lrw r1,2 */
26044998 497 0x81, 0x01, /* ld.w r1,(r1,0) */
ba8c44fc
NC
498 0x00, 0xC1, /* jmp r1 */
499 0x12, 0x00, /* nop */
26044998 500 0x00, 0x00, 0x00, 0x00 /* <address> */
661016bb
NC
501};
502
503static const unsigned char mcore_le_jtab[] =
504{
ba8c44fc 505 0x02, 0x71, /* lrw r1,2 */
26044998 506 0x01, 0x81, /* ld.w r1,(r1,0) */
ba8c44fc
NC
507 0xC1, 0x00, /* jmp r1 */
508 0x00, 0x12, /* nop */
26044998 509 0x00, 0x00, 0x00, 0x00 /* <address> */
661016bb
NC
510};
511
c9e38879
NC
512/* This is the glue sequence for PowerPC PE. There is a
513 tocrel16-tocdefn reloc against the first instruction.
514 We also need a IMGLUE reloc against the glue function
515 to restore the toc saved by the third instruction in
516 the glue. */
252b5132
RH
517static const unsigned char ppc_jtab[] =
518{
519 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
520 /* Reloc TOCREL16 __imp_xxx */
521 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
522 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
523 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
524 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
525 0x20, 0x04, 0x80, 0x4E /* bctr */
526};
527
528#ifdef DLLTOOL_PPC
c9e38879
NC
529/* The glue instruction, picks up the toc from the stw in
530 the above code: "lwz r2,4(r1)". */
252b5132
RH
531static bfd_vma ppc_glue_insn = 0x80410004;
532#endif
533
252b5132
RH
534struct mac
535 {
536 const char *type;
537 const char *how_byte;
538 const char *how_short;
539 const char *how_long;
540 const char *how_asciz;
541 const char *how_comment;
542 const char *how_jump;
543 const char *how_global;
544 const char *how_space;
545 const char *how_align_short;
546 const char *how_align_long;
49c24507 547 const char *how_default_as_switches;
252b5132
RH
548 const char *how_bfd_target;
549 enum bfd_architecture how_bfd_arch;
550 const unsigned char *how_jtab;
c9e38879
NC
551 int how_jtab_size; /* Size of the jtab entry. */
552 int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5. */
252b5132
RH
553 };
554
555static const struct mac
556mtable[] =
557{
558 {
559#define MARM 0
560 "arm", ".byte", ".short", ".long", ".asciz", "@",
561 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
eaeaa15c 562 ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
49c24507 563 "pe-arm-little", bfd_arch_arm,
252b5132
RH
564 arm_jtab, sizeof (arm_jtab), 8
565 }
566 ,
567 {
568#define M386 1
49c24507
NC
569 "i386", ".byte", ".short", ".long", ".asciz", "#",
570 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
571 "pe-i386",bfd_arch_i386,
572 i386_jtab, sizeof (i386_jtab), 2
252b5132
RH
573 }
574 ,
575 {
576#define MPPC 2
49c24507
NC
577 "ppc", ".byte", ".short", ".long", ".asciz", "#",
578 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
579 "pe-powerpcle",bfd_arch_powerpc,
580 ppc_jtab, sizeof (ppc_jtab), 0
252b5132
RH
581 }
582 ,
583 {
584#define MTHUMB 3
585 "thumb", ".byte", ".short", ".long", ".asciz", "@",
b890a735 586 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
a2186dfe 587 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
49c24507 588 "pe-arm-little", bfd_arch_arm,
252b5132
RH
589 thumb_jtab, sizeof (thumb_jtab), 12
590 }
591 ,
b890a735
CM
592#define MARM_INTERWORK 4
593 {
594 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
595 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
49c24507
NC
596 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
597 "pe-arm-little", bfd_arch_arm,
b890a735
CM
598 arm_interwork_jtab, sizeof (arm_interwork_jtab), 12
599 }
600 ,
661016bb
NC
601 {
602#define MMCORE_BE 5
7e301c9c 603 "mcore-be", ".byte", ".short", ".long", ".asciz", "//",
ba8c44fc 604 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
49c24507
NC
605 ".global", ".space", ".align\t2",".align\t4", "",
606 "pe-mcore-big", bfd_arch_mcore,
ba8c44fc 607 mcore_be_jtab, sizeof (mcore_be_jtab), 8
661016bb
NC
608 }
609 ,
610 {
611#define MMCORE_LE 6
612 "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
ba8c44fc 613 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
49c24507
NC
614 ".global", ".space", ".align\t2",".align\t4", "-EL",
615 "pe-mcore-little", bfd_arch_mcore,
ba8c44fc 616 mcore_le_jtab, sizeof (mcore_le_jtab), 8
661016bb
NC
617 }
618 ,
619 {
620#define MMCORE_ELF 7
7e301c9c 621 "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
ba8c44fc 622 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
49c24507
NC
623 ".global", ".space", ".align\t2",".align\t4", "",
624 "elf32-mcore-big", bfd_arch_mcore,
ba8c44fc 625 mcore_be_jtab, sizeof (mcore_be_jtab), 8
661016bb
NC
626 }
627 ,
628 {
629#define MMCORE_ELF_LE 8
630 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
ba8c44fc 631 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
49c24507
NC
632 ".global", ".space", ".align\t2",".align\t4", "-EL",
633 "elf32-mcore-little", bfd_arch_mcore,
ba8c44fc 634 mcore_le_jtab, sizeof (mcore_le_jtab), 8
661016bb
NC
635 }
636 ,
a2186dfe
NC
637 {
638#define MARM_EPOC 9
a8c548cb 639 "arm-epoc", ".byte", ".short", ".long", ".asciz", "@",
a2186dfe
NC
640 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
641 ".global", ".space", ".align\t2",".align\t4", "",
642 "epoc-pe-arm-little", bfd_arch_arm,
643 arm_jtab, sizeof (arm_jtab), 8
644 }
645 ,
7148cc28
NC
646 {
647#define MARM_WINCE 10
648 "arm-wince", ".byte", ".short", ".long", ".asciz", "@",
649 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
650 ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
651 "pe-arm-wince-little", bfd_arch_arm,
652 arm_jtab, sizeof (arm_jtab), 8
653 }
654 ,
99ad8390
NC
655 {
656#define MX86 11
657 "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
658 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
659 "pe-x86-64",bfd_arch_i386,
660 i386_jtab, sizeof (i386_jtab), 2
661 }
662 ,
5ea695ed 663 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
252b5132
RH
664};
665
666typedef struct dlist
667{
668 char *text;
669 struct dlist *next;
670}
671dlist_type;
672
673typedef struct export
674 {
675 const char *name;
676 const char *internal_name;
0fd555c4 677 const char *import_name;
252b5132
RH
678 int ordinal;
679 int constant;
7aa52b1f
NC
680 int noname; /* Don't put name in image file. */
681 int private; /* Don't put reference in import lib. */
252b5132
RH
682 int data;
683 int hint;
c9e38879 684 int forward; /* Number of forward label, 0 means no forward. */
252b5132
RH
685 struct export *next;
686 }
687export_type;
688
689/* A list of symbols which we should not export. */
26044998 690
252b5132
RH
691struct string_list
692{
693 struct string_list *next;
694 char *string;
695};
696
697static struct string_list *excludes;
698
2da42df6
AJ
699static const char *rvaafter (int);
700static const char *rvabefore (int);
2758961a 701static const char *asm_prefix (int, const char *);
2da42df6
AJ
702static void process_def_file (const char *);
703static void new_directive (char *);
704static void append_import (const char *, const char *, int);
705static void run (const char *, char *);
706static void scan_drectve_symbols (bfd *);
707static void scan_filtered_symbols (bfd *, void *, long, unsigned int);
708static void add_excludes (const char *);
709static bfd_boolean match_exclude (const char *);
710static void set_default_excludes (void);
711static long filter_symbols (bfd *, void *, long, unsigned int);
712static void scan_all_symbols (bfd *);
713static void scan_open_obj_file (bfd *);
714static void scan_obj_file (const char *);
715static void dump_def_info (FILE *);
716static int sfunc (const void *, const void *);
d078078d 717static void flush_page (FILE *, bfd_vma *, bfd_vma, int);
2da42df6
AJ
718static void gen_def_file (void);
719static void generate_idata_ofile (FILE *);
720static void assemble_file (const char *, const char *);
721static void gen_exp_file (void);
722static const char *xlate (const char *);
2da42df6
AJ
723static char *make_label (const char *, const char *);
724static char *make_imp_label (const char *, const char *);
725static bfd *make_one_lib_file (export_type *, int);
726static bfd *make_head (void);
727static bfd *make_tail (void);
728static void gen_lib_file (void);
d4732f7c
CW
729static void identify_dll_for_implib (void);
730static void identify_search_archive (bfd*);
731static void identify_search_member (bfd*, bfd*);
732static bfd_boolean identify_process_section_p (asection *);
733static void identify_search_section (bfd *, asection *, void *);
2da42df6
AJ
734static int pfunc (const void *, const void *);
735static int nfunc (const void *, const void *);
736static void remove_null_names (export_type **);
2da42df6
AJ
737static void process_duplicates (export_type **);
738static void fill_ordinals (export_type **);
2da42df6
AJ
739static void mangle_defs (void);
740static void usage (FILE *, int);
0fd3a477 741static void inform (const char *, ...) ATTRIBUTE_PRINTF_1;
a0ce7f12 742static void set_dll_name_from_def (const char *);
252b5132 743
0e11a9e9 744static char *
739fea7b 745prefix_encode (char *start, unsigned code)
bf7a6389 746{
ff6b6222 747 static char alpha[26] = "abcdefghijklmnopqrstuvwxyz";
bf7a6389
CF
748 static char buf[32];
749 char *p;
739fea7b 750 strcpy (buf, start);
bf7a6389
CF
751 p = strchr (buf, '\0');
752 do
753 *p++ = alpha[code % sizeof (alpha)];
754 while ((code /= sizeof (alpha)) != 0);
755 *p = '\0';
0e11a9e9
CF
756 return buf;
757}
252b5132 758
bf7a6389 759static char *
739fea7b 760dlltmp (char **buf, const char *fmt)
bf7a6389
CF
761{
762 if (!*buf)
763 {
739fea7b 764 *buf = malloc (strlen (tmp_prefix) + 64);
bf7a6389
CF
765 sprintf (*buf, fmt, tmp_prefix);
766 }
767 return *buf;
768}
769
252b5132 770static void
c9e38879 771inform VPARAMS ((const char * message, ...))
252b5132 772{
e80ff7de
AM
773 VA_OPEN (args, message);
774 VA_FIXEDARG (args, const char *, message);
775
252b5132
RH
776 if (!verbose)
777 return;
778
37cc8ec1 779 report (message, args);
e80ff7de
AM
780
781 VA_CLOSE (args);
252b5132
RH
782}
783
252b5132 784static const char *
2da42df6 785rvaafter (int machine)
252b5132
RH
786{
787 switch (machine)
788 {
789 case MARM:
790 case M386:
99ad8390 791 case MX86:
252b5132
RH
792 case MPPC:
793 case MTHUMB:
b890a735 794 case MARM_INTERWORK:
661016bb
NC
795 case MMCORE_BE:
796 case MMCORE_LE:
797 case MMCORE_ELF:
798 case MMCORE_ELF_LE:
a8c548cb 799 case MARM_EPOC:
7148cc28 800 case MARM_WINCE:
252b5132
RH
801 break;
802 default:
803 /* xgettext:c-format */
37cc8ec1 804 fatal (_("Internal error: Unknown machine type: %d"), machine);
252b5132
RH
805 break;
806 }
807 return "";
808}
809
810static const char *
2da42df6 811rvabefore (int machine)
252b5132
RH
812{
813 switch (machine)
814 {
815 case MARM:
816 case M386:
99ad8390 817 case MX86:
252b5132
RH
818 case MPPC:
819 case MTHUMB:
b890a735 820 case MARM_INTERWORK:
661016bb
NC
821 case MMCORE_BE:
822 case MMCORE_LE:
823 case MMCORE_ELF:
824 case MMCORE_ELF_LE:
a8c548cb 825 case MARM_EPOC:
7148cc28 826 case MARM_WINCE:
252b5132
RH
827 return ".rva\t";
828 default:
829 /* xgettext:c-format */
37cc8ec1 830 fatal (_("Internal error: Unknown machine type: %d"), machine);
252b5132
RH
831 break;
832 }
833 return "";
834}
835
836static const char *
2758961a 837asm_prefix (int machine, const char *name)
252b5132
RH
838{
839 switch (machine)
840 {
841 case MARM:
842 case MPPC:
843 case MTHUMB:
b890a735 844 case MARM_INTERWORK:
661016bb
NC
845 case MMCORE_BE:
846 case MMCORE_LE:
847 case MMCORE_ELF:
848 case MMCORE_ELF_LE:
a8c548cb 849 case MARM_EPOC:
7148cc28 850 case MARM_WINCE:
252b5132
RH
851 break;
852 case M386:
99ad8390 853 case MX86:
2758961a
NC
854 /* Symbol names starting with ? do not have a leading underscore. */
855 if (name && *name == '?')
856 break;
857 else
858 return "_";
252b5132
RH
859 default:
860 /* xgettext:c-format */
37cc8ec1 861 fatal (_("Internal error: Unknown machine type: %d"), machine);
252b5132
RH
862 break;
863 }
864 return "";
865}
866
2758961a
NC
867#define ASM_BYTE mtable[machine].how_byte
868#define ASM_SHORT mtable[machine].how_short
869#define ASM_LONG mtable[machine].how_long
870#define ASM_TEXT mtable[machine].how_asciz
871#define ASM_C mtable[machine].how_comment
872#define ASM_JUMP mtable[machine].how_jump
873#define ASM_GLOBAL mtable[machine].how_global
874#define ASM_SPACE mtable[machine].how_space
875#define ASM_ALIGN_SHORT mtable[machine].how_align_short
876#define ASM_RVA_BEFORE rvabefore (machine)
877#define ASM_RVA_AFTER rvaafter (machine)
878#define ASM_PREFIX(NAME) asm_prefix (machine, (NAME))
879#define ASM_ALIGN_LONG mtable[machine].how_align_long
880#define HOW_BFD_READ_TARGET 0 /* Always default. */
881#define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target
882#define HOW_BFD_ARCH mtable[machine].how_bfd_arch
883#define HOW_JTAB mtable[machine].how_jtab
884#define HOW_JTAB_SIZE mtable[machine].how_jtab_size
885#define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
886#define ASM_SWITCHES mtable[machine].how_default_as_switches
49c24507 887
252b5132
RH
888static char **oav;
889
e80ff7de 890static void
2da42df6 891process_def_file (const char *name)
252b5132
RH
892{
893 FILE *f = fopen (name, FOPEN_RT);
26044998 894
252b5132
RH
895 if (!f)
896 /* xgettext:c-format */
897 fatal (_("Can't open def file: %s"), name);
898
899 yyin = f;
900
901 /* xgettext:c-format */
902 inform (_("Processing def file: %s"), name);
26044998 903
252b5132
RH
904 yyparse ();
905
906 inform (_("Processed def file"));
907}
908
909/**********************************************************************/
910
c9e38879 911/* Communications with the parser. */
252b5132 912
c9e38879
NC
913static int d_nfuncs; /* Number of functions exported. */
914static int d_named_nfuncs; /* Number of named functions exported. */
915static int d_low_ord; /* Lowest ordinal index. */
916static int d_high_ord; /* Highest ordinal index. */
917static export_type *d_exports; /* List of exported functions. */
918static export_type **d_exports_lexically; /* Vector of exported functions in alpha order. */
919static dlist_type *d_list; /* Descriptions. */
920static dlist_type *a_list; /* Stuff to go in directives. */
921static int d_nforwards = 0; /* Number of forwarded exports. */
252b5132
RH
922
923static int d_is_dll;
924static int d_is_exe;
925
926int
2da42df6 927yyerror (const char * err ATTRIBUTE_UNUSED)
252b5132
RH
928{
929 /* xgettext:c-format */
37cc8ec1 930 non_fatal (_("Syntax error in def file %s:%d"), def_file, linenumber);
26044998 931
252b5132
RH
932 return 0;
933}
934
935void
2da42df6 936def_exports (const char *name, const char *internal_name, int ordinal,
7aa52b1f 937 int noname, int constant, int data, int private)
252b5132
RH
938{
939 struct export *p = (struct export *) xmalloc (sizeof (*p));
940
941 p->name = name;
942 p->internal_name = internal_name ? internal_name : name;
0fd555c4 943 p->import_name = name;
252b5132
RH
944 p->ordinal = ordinal;
945 p->constant = constant;
946 p->noname = noname;
7aa52b1f 947 p->private = private;
252b5132
RH
948 p->data = data;
949 p->next = d_exports;
950 d_exports = p;
951 d_nfuncs++;
26044998
KH
952
953 if ((internal_name != NULL)
04847a4d
CF
954 && (strchr (internal_name, '.') != NULL))
955 p->forward = ++d_nforwards;
956 else
957 p->forward = 0; /* no forward */
252b5132
RH
958}
959
a0ce7f12
DS
960static void
961set_dll_name_from_def (const char * name)
962{
963 const char* image_basename = lbasename (name);
964 if (image_basename != name)
965 non_fatal (_("%s: Path components stripped from image name, '%s'."),
966 def_file, name);
967 dll_name = xstrdup (image_basename);
968}
969
252b5132 970void
2da42df6 971def_name (const char *name, int base)
252b5132
RH
972{
973 /* xgettext:c-format */
974 inform (_("NAME: %s base: %x"), name, base);
26044998 975
252b5132 976 if (d_is_dll)
37cc8ec1 977 non_fatal (_("Can't have LIBRARY and NAME"));
26044998 978
c9e38879
NC
979 /* If --dllname not provided, use the one in the DEF file.
980 FIXME: Is this appropriate for executables? */
252b5132 981 if (! dll_name)
a0ce7f12 982 set_dll_name_from_def (name);
252b5132
RH
983 d_is_exe = 1;
984}
985
986void
2da42df6 987def_library (const char *name, int base)
252b5132
RH
988{
989 /* xgettext:c-format */
990 inform (_("LIBRARY: %s base: %x"), name, base);
26044998 991
252b5132 992 if (d_is_exe)
37cc8ec1 993 non_fatal (_("Can't have LIBRARY and NAME"));
26044998 994
c9e38879 995 /* If --dllname not provided, use the one in the DEF file. */
252b5132 996 if (! dll_name)
a0ce7f12 997 set_dll_name_from_def (name);
252b5132
RH
998 d_is_dll = 1;
999}
1000
1001void
2da42df6 1002def_description (const char *desc)
252b5132
RH
1003{
1004 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1005 d->text = xstrdup (desc);
1006 d->next = d_list;
1007 d_list = d;
1008}
1009
e80ff7de 1010static void
2da42df6 1011new_directive (char *dir)
252b5132
RH
1012{
1013 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1014 d->text = xstrdup (dir);
1015 d->next = a_list;
1016 a_list = d;
1017}
1018
1019void
2da42df6 1020def_heapsize (int reserve, int commit)
252b5132
RH
1021{
1022 char b[200];
1023 if (commit > 0)
1024 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
1025 else
1026 sprintf (b, "-heap 0x%x ", reserve);
1027 new_directive (xstrdup (b));
1028}
1029
1030void
2da42df6 1031def_stacksize (int reserve, int commit)
252b5132
RH
1032{
1033 char b[200];
1034 if (commit > 0)
1035 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
1036 else
1037 sprintf (b, "-stack 0x%x ", reserve);
1038 new_directive (xstrdup (b));
1039}
1040
1041/* append_import simply adds the given import definition to the global
1042 import_list. It is used by def_import. */
1043
1044static void
2da42df6 1045append_import (const char *symbol_name, const char *dll_name, int func_ordinal)
252b5132
RH
1046{
1047 iheadtype **pq;
1048 iheadtype *q;
1049
1050 for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
1051 {
1052 if (strcmp ((*pq)->dllname, dll_name) == 0)
1053 {
1054 q = *pq;
1055 q->functail->next = xmalloc (sizeof (ifunctype));
1056 q->functail = q->functail->next;
1057 q->functail->ord = func_ordinal;
1058 q->functail->name = xstrdup (symbol_name);
1059 q->functail->next = NULL;
1060 q->nfuncs++;
1061 return;
1062 }
1063 }
1064
1065 q = xmalloc (sizeof (iheadtype));
1066 q->dllname = xstrdup (dll_name);
1067 q->nfuncs = 1;
1068 q->funchead = xmalloc (sizeof (ifunctype));
1069 q->functail = q->funchead;
1070 q->next = NULL;
1071 q->functail->name = xstrdup (symbol_name);
1072 q->functail->ord = func_ordinal;
1073 q->functail->next = NULL;
1074
1075 *pq = q;
1076}
1077
1078/* def_import is called from within defparse.y when an IMPORT
1079 declaration is encountered. Depending on the form of the
1080 declaration, the module name may or may not need ".dll" to be
1081 appended to it, the name of the function may be stored in internal
1082 or entry, and there may or may not be an ordinal value associated
1083 with it. */
1084
1085/* A note regarding the parse modes:
1086 In defparse.y we have to accept import declarations which follow
1087 any one of the following forms:
1088 <func_name_in_app> = <dll_name>.<func_name_in_dll>
1089 <func_name_in_app> = <dll_name>.<number>
1090 <dll_name>.<func_name_in_dll>
1091 <dll_name>.<number>
1092 Furthermore, the dll's name may or may not end with ".dll", which
1093 complicates the parsing a little. Normally the dll's name is
1094 passed to def_import() in the "module" parameter, but when it ends
1095 with ".dll" it gets passed in "module" sans ".dll" and that needs
1096 to be reappended.
1097
1098 def_import gets five parameters:
1099 APP_NAME - the name of the function in the application, if
1100 present, or NULL if not present.
1101 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
1102 DLLEXT - the extension of the dll, if present, NULL if not present.
1103 ENTRY - the name of the function in the dll, if present, or NULL.
1104 ORD_VAL - the numerical tag of the function in the dll, if present,
1105 or NULL. Exactly one of <entry> or <ord_val> must be
1106 present (i.e., not NULL). */
1107
1108void
2da42df6
AJ
1109def_import (const char *app_name, const char *module, const char *dllext,
1110 const char *entry, int ord_val)
252b5132
RH
1111{
1112 const char *application_name;
1113 char *buf;
1114
1115 if (entry != NULL)
1116 application_name = entry;
1117 else
1118 {
1119 if (app_name != NULL)
1120 application_name = app_name;
1121 else
1122 application_name = "";
1123 }
26044998 1124
252b5132
RH
1125 if (dllext != NULL)
1126 {
1127 buf = (char *) alloca (strlen (module) + strlen (dllext) + 2);
1128 sprintf (buf, "%s.%s", module, dllext);
1129 module = buf;
1130 }
1131
1132 append_import (application_name, module, ord_val);
1133}
1134
1135void
2da42df6 1136def_version (int major, int minor)
252b5132
RH
1137{
1138 printf ("VERSION %d.%d\n", major, minor);
1139}
1140
1141void
2da42df6 1142def_section (const char *name, int attr)
252b5132
RH
1143{
1144 char buf[200];
1145 char atts[5];
1146 char *d = atts;
1147 if (attr & 1)
1148 *d++ = 'R';
1149
1150 if (attr & 2)
1151 *d++ = 'W';
1152 if (attr & 4)
1153 *d++ = 'X';
1154 if (attr & 8)
1155 *d++ = 'S';
1156 *d++ = 0;
1157 sprintf (buf, "-attr %s %s", name, atts);
1158 new_directive (xstrdup (buf));
1159}
1160
1161void
2da42df6 1162def_code (int attr)
252b5132
RH
1163{
1164
1165 def_section ("CODE", attr);
1166}
1167
1168void
2da42df6 1169def_data (int attr)
252b5132
RH
1170{
1171 def_section ("DATA", attr);
1172}
1173
1174/**********************************************************************/
1175
1176static void
2da42df6 1177run (const char *what, char *args)
252b5132
RH
1178{
1179 char *s;
1180 int pid, wait_status;
1181 int i;
1182 const char **argv;
1183 char *errmsg_fmt, *errmsg_arg;
1184 char *temp_base = choose_temp_base ();
1185
37cc8ec1 1186 inform ("run: %s %s", what, args);
252b5132
RH
1187
1188 /* Count the args */
1189 i = 0;
1190 for (s = args; *s; s++)
1191 if (*s == ' ')
1192 i++;
1193 i++;
1194 argv = alloca (sizeof (char *) * (i + 3));
1195 i = 0;
1196 argv[i++] = what;
1197 s = args;
1198 while (1)
1199 {
1200 while (*s == ' ')
1201 ++s;
1202 argv[i++] = s;
1203 while (*s != ' ' && *s != 0)
1204 s++;
1205 if (*s == 0)
1206 break;
1207 *s++ = 0;
1208 }
1209 argv[i++] = NULL;
1210
1211 pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
1212 &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
1213
1214 if (pid == -1)
1215 {
1216 inform (strerror (errno));
26044998 1217
252b5132
RH
1218 fatal (errmsg_fmt, errmsg_arg);
1219 }
1220
1221 pid = pwait (pid, & wait_status, 0);
26044998 1222
252b5132
RH
1223 if (pid == -1)
1224 {
1225 /* xgettext:c-format */
1226 fatal (_("wait: %s"), strerror (errno));
1227 }
1228 else if (WIFSIGNALED (wait_status))
1229 {
1230 /* xgettext:c-format */
1231 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
1232 }
1233 else if (WIFEXITED (wait_status))
1234 {
1235 if (WEXITSTATUS (wait_status) != 0)
1236 /* xgettext:c-format */
37cc8ec1
AM
1237 non_fatal (_("%s exited with status %d"),
1238 what, WEXITSTATUS (wait_status));
252b5132
RH
1239 }
1240 else
1241 abort ();
1242}
1243
1244/* Look for a list of symbols to export in the .drectve section of
1245 ABFD. Pass each one to def_exports. */
1246
1247static void
2da42df6 1248scan_drectve_symbols (bfd *abfd)
252b5132
RH
1249{
1250 asection * s;
1251 int size;
1252 char * buf;
1253 char * p;
1254 char * e;
661016bb 1255
252b5132 1256 /* Look for .drectve's */
661016bb 1257 s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME);
26044998 1258
252b5132
RH
1259 if (s == NULL)
1260 return;
26044998 1261
135dfb4a 1262 size = bfd_get_section_size (s);
252b5132
RH
1263 buf = xmalloc (size);
1264
1265 bfd_get_section_contents (abfd, s, buf, 0, size);
26044998 1266
252b5132 1267 /* xgettext:c-format */
37cc8ec1 1268 inform (_("Sucking in info from %s section in %s"),
661016bb 1269 DRECTVE_SECTION_NAME, bfd_get_filename (abfd));
252b5132 1270
ce195b42
DD
1271 /* Search for -export: strings. The exported symbols can optionally
1272 have type tags (eg., -export:foo,data), so handle those as well.
5f0f29c3 1273 Currently only data tag is supported. */
252b5132
RH
1274 p = buf;
1275 e = buf + size;
1276 while (p < e)
1277 {
1278 if (p[0] == '-'
0112cd26 1279 && CONST_STRNEQ (p, "-export:"))
252b5132
RH
1280 {
1281 char * name;
1282 char * c;
ce195b42 1283 flagword flags = BSF_FUNCTION;
26044998 1284
252b5132
RH
1285 p += 8;
1286 name = p;
ce195b42 1287 while (p < e && *p != ',' && *p != ' ' && *p != '-')
252b5132
RH
1288 p++;
1289 c = xmalloc (p - name + 1);
1290 memcpy (c, name, p - name);
1291 c[p - name] = 0;
26044998 1292 if (p < e && *p == ',') /* found type tag. */
ce195b42
DD
1293 {
1294 char *tag_start = ++p;
1295 while (p < e && *p != ' ' && *p != '-')
1296 p++;
0112cd26 1297 if (CONST_STRNEQ (tag_start, "data"))
ce195b42
DD
1298 flags &= ~BSF_FUNCTION;
1299 }
1300
252b5132
RH
1301 /* FIXME: The 5th arg is for the `constant' field.
1302 What should it be? Not that it matters since it's not
1303 currently useful. */
7aa52b1f 1304 def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0);
252b5132
RH
1305
1306 if (add_stdcall_alias && strchr (c, '@'))
1307 {
b34976b6 1308 int lead_at = (*c == '@') ;
c9e38879 1309 char *exported_name = xstrdup (c + lead_at);
252b5132
RH
1310 char *atsym = strchr (exported_name, '@');
1311 *atsym = '\0';
5f0f29c3 1312 /* Note: stdcall alias symbols can never be data. */
7aa52b1f 1313 def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0);
252b5132
RH
1314 }
1315 }
1316 else
1317 p++;
1318 }
1319 free (buf);
1320}
1321
1322/* Look through the symbols in MINISYMS, and add each one to list of
1323 symbols to export. */
1324
1325static void
2da42df6
AJ
1326scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount,
1327 unsigned int size)
252b5132
RH
1328{
1329 asymbol *store;
1330 bfd_byte *from, *fromend;
1331
1332 store = bfd_make_empty_symbol (abfd);
1333 if (store == NULL)
1334 bfd_fatal (bfd_get_filename (abfd));
1335
1336 from = (bfd_byte *) minisyms;
1337 fromend = from + symcount * size;
1338 for (; from < fromend; from += size)
1339 {
1340 asymbol *sym;
1341 const char *symbol_name;
1342
b34976b6 1343 sym = bfd_minisymbol_to_symbol (abfd, FALSE, from, store);
252b5132
RH
1344 if (sym == NULL)
1345 bfd_fatal (bfd_get_filename (abfd));
1346
1347 symbol_name = bfd_asymbol_name (sym);
1348 if (bfd_get_symbol_leading_char (abfd) == symbol_name[0])
1349 ++symbol_name;
1350
ce195b42 1351 def_exports (xstrdup (symbol_name) , 0, -1, 0, 0,
7aa52b1f 1352 ! (sym->flags & BSF_FUNCTION), 0);
252b5132
RH
1353
1354 if (add_stdcall_alias && strchr (symbol_name, '@'))
1355 {
c9e38879
NC
1356 int lead_at = (*symbol_name == '@');
1357 char *exported_name = xstrdup (symbol_name + lead_at);
252b5132
RH
1358 char *atsym = strchr (exported_name, '@');
1359 *atsym = '\0';
26044998 1360 /* Note: stdcall alias symbols can never be data. */
7aa52b1f 1361 def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0, 0);
252b5132
RH
1362 }
1363 }
1364}
1365
1366/* Add a list of symbols to exclude. */
1367
1368static void
2da42df6 1369add_excludes (const char *new_excludes)
252b5132
RH
1370{
1371 char *local_copy;
1372 char *exclude_string;
1373
1374 local_copy = xstrdup (new_excludes);
1375
1376 exclude_string = strtok (local_copy, ",:");
1377 for (; exclude_string; exclude_string = strtok (NULL, ",:"))
1378 {
1379 struct string_list *new_exclude;
26044998 1380
252b5132
RH
1381 new_exclude = ((struct string_list *)
1382 xmalloc (sizeof (struct string_list)));
1383 new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2);
c9e38879
NC
1384 /* Don't add a leading underscore for fastcall symbols. */
1385 if (*exclude_string == '@')
1386 sprintf (new_exclude->string, "%s", exclude_string);
1387 else
1388 sprintf (new_exclude->string, "_%s", exclude_string);
252b5132
RH
1389 new_exclude->next = excludes;
1390 excludes = new_exclude;
1391
1392 /* xgettext:c-format */
37cc8ec1 1393 inform (_("Excluding symbol: %s"), exclude_string);
252b5132
RH
1394 }
1395
1396 free (local_copy);
1397}
1398
1399/* See if STRING is on the list of symbols to exclude. */
1400
b34976b6 1401static bfd_boolean
2da42df6 1402match_exclude (const char *string)
252b5132
RH
1403{
1404 struct string_list *excl_item;
1405
1406 for (excl_item = excludes; excl_item; excl_item = excl_item->next)
1407 if (strcmp (string, excl_item->string) == 0)
b34976b6
AM
1408 return TRUE;
1409 return FALSE;
252b5132
RH
1410}
1411
1412/* Add the default list of symbols to exclude. */
1413
1414static void
1415set_default_excludes (void)
1416{
1417 add_excludes (default_excludes);
1418}
1419
1420/* Choose which symbols to export. */
1421
1422static long
2da42df6 1423filter_symbols (bfd *abfd, void *minisyms, long symcount, unsigned int size)
252b5132
RH
1424{
1425 bfd_byte *from, *fromend, *to;
1426 asymbol *store;
1427
1428 store = bfd_make_empty_symbol (abfd);
1429 if (store == NULL)
1430 bfd_fatal (bfd_get_filename (abfd));
1431
1432 from = (bfd_byte *) minisyms;
1433 fromend = from + symcount * size;
1434 to = (bfd_byte *) minisyms;
1435
1436 for (; from < fromend; from += size)
1437 {
1438 int keep = 0;
1439 asymbol *sym;
1440
2da42df6 1441 sym = bfd_minisymbol_to_symbol (abfd, FALSE, (const void *) from, store);
252b5132
RH
1442 if (sym == NULL)
1443 bfd_fatal (bfd_get_filename (abfd));
1444
1445 /* Check for external and defined only symbols. */
1446 keep = (((sym->flags & BSF_GLOBAL) != 0
1447 || (sym->flags & BSF_WEAK) != 0
1448 || bfd_is_com_section (sym->section))
1449 && ! bfd_is_und_section (sym->section));
26044998 1450
252b5132
RH
1451 keep = keep && ! match_exclude (sym->name);
1452
1453 if (keep)
1454 {
1455 memcpy (to, from, size);
1456 to += size;
1457 }
1458 }
1459
1460 return (to - (bfd_byte *) minisyms) / size;
1461}
1462
1463/* Export all symbols in ABFD, except for ones we were told not to
1464 export. */
1465
1466static void
2da42df6 1467scan_all_symbols (bfd *abfd)
252b5132
RH
1468{
1469 long symcount;
2da42df6 1470 void *minisyms;
252b5132
RH
1471 unsigned int size;
1472
1473 /* Ignore bfds with an import descriptor table. We assume that any
1474 such BFD contains symbols which are exported from another DLL,
1475 and we don't want to reexport them from here. */
1476 if (bfd_get_section_by_name (abfd, ".idata$4"))
1477 return;
1478
1479 if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
1480 {
1481 /* xgettext:c-format */
37cc8ec1 1482 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
252b5132
RH
1483 return;
1484 }
1485
b34976b6 1486 symcount = bfd_read_minisymbols (abfd, FALSE, &minisyms, &size);
252b5132
RH
1487 if (symcount < 0)
1488 bfd_fatal (bfd_get_filename (abfd));
1489
1490 if (symcount == 0)
1491 {
1492 /* xgettext:c-format */
37cc8ec1 1493 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
252b5132
RH
1494 return;
1495 }
1496
1497 /* Discard the symbols we don't want to export. It's OK to do this
1498 in place; we'll free the storage anyway. */
1499
1500 symcount = filter_symbols (abfd, minisyms, symcount, size);
1501 scan_filtered_symbols (abfd, minisyms, symcount, size);
1502
1503 free (minisyms);
1504}
1505
1506/* Look at the object file to decide which symbols to export. */
1507
1508static void
2da42df6 1509scan_open_obj_file (bfd *abfd)
252b5132
RH
1510{
1511 if (export_all_symbols)
1512 scan_all_symbols (abfd);
1513 else
1514 scan_drectve_symbols (abfd);
26044998 1515
c9e38879 1516 /* FIXME: we ought to read in and block out the base relocations. */
252b5132
RH
1517
1518 /* xgettext:c-format */
37cc8ec1 1519 inform (_("Done reading %s"), bfd_get_filename (abfd));
252b5132
RH
1520}
1521
1522static void
2da42df6 1523scan_obj_file (const char *filename)
252b5132
RH
1524{
1525 bfd * f = bfd_openr (filename, 0);
1526
1527 if (!f)
1528 /* xgettext:c-format */
1529 fatal (_("Unable to open object file: %s"), filename);
1530
1531 /* xgettext:c-format */
1532 inform (_("Scanning object file %s"), filename);
26044998 1533
252b5132
RH
1534 if (bfd_check_format (f, bfd_archive))
1535 {
1536 bfd *arfile = bfd_openr_next_archived_file (f, 0);
1537 while (arfile)
1538 {
1539 if (bfd_check_format (arfile, bfd_object))
1540 scan_open_obj_file (arfile);
1541 bfd_close (arfile);
1542 arfile = bfd_openr_next_archived_file (f, arfile);
1543 }
26044998 1544
49e315b1
NC
1545#ifdef DLLTOOL_MCORE_ELF
1546 if (mcore_elf_out_file)
1547 inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename);
1548#endif
252b5132
RH
1549 }
1550 else if (bfd_check_format (f, bfd_object))
1551 {
1552 scan_open_obj_file (f);
49e315b1
NC
1553
1554#ifdef DLLTOOL_MCORE_ELF
1555 if (mcore_elf_out_file)
fd64a958 1556 mcore_elf_cache_filename (filename);
49e315b1 1557#endif
252b5132
RH
1558 }
1559
1560 bfd_close (f);
1561}
1562
1563/**********************************************************************/
1564
1565static void
2da42df6 1566dump_def_info (FILE *f)
252b5132
RH
1567{
1568 int i;
1569 export_type *exp;
1570 fprintf (f, "%s ", ASM_C);
1571 for (i = 0; oav[i]; i++)
1572 fprintf (f, "%s ", oav[i]);
1573 fprintf (f, "\n");
1574 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1575 {
7aa52b1f 1576 fprintf (f, "%s %d = %s %s @ %d %s%s%s%s\n",
252b5132
RH
1577 ASM_C,
1578 i,
1579 exp->name,
1580 exp->internal_name,
1581 exp->ordinal,
1582 exp->noname ? "NONAME " : "",
7aa52b1f 1583 exp->private ? "PRIVATE " : "",
252b5132
RH
1584 exp->constant ? "CONSTANT" : "",
1585 exp->data ? "DATA" : "");
1586 }
1587}
1588
c9e38879 1589/* Generate the .exp file. */
252b5132
RH
1590
1591static int
2da42df6 1592sfunc (const void *a, const void *b)
252b5132 1593{
d078078d
KT
1594 if (*(const bfd_vma *) a == *(const bfd_vma *) b)
1595 return 0;
1596
1597 return ((*(const bfd_vma *) a > *(const bfd_vma *) b) ? 1 : -1);
252b5132
RH
1598}
1599
1600static void
d078078d 1601flush_page (FILE *f, bfd_vma *need, bfd_vma page_addr, int on_page)
252b5132
RH
1602{
1603 int i;
1604
c9e38879 1605 /* Flush this page. */
252b5132
RH
1606 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1607 ASM_LONG,
d078078d 1608 (int) page_addr,
252b5132
RH
1609 ASM_C);
1610 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1611 ASM_LONG,
1612 (on_page * 2) + (on_page & 1) * 2 + 8,
1613 ASM_C);
26044998 1614
252b5132 1615 for (i = 0; i < on_page; i++)
a2186dfe 1616 {
d078078d 1617 bfd_vma needed = need[i];
26044998 1618
a2186dfe 1619 if (needed)
d078078d
KT
1620 {
1621#ifndef DLLTOOL_MX86_64
1622 /* Relocation via HIGHLOW. */
1623 needed = ((needed - page_addr) | 0x3000) & 0xffff;
1624#else
1625 /* Relocation via DIR64. */
1626 needed = ((needed - page_addr) | 0xa000) & 0xffff;
1627#endif
1628 }
26044998 1629
d078078d 1630 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (long) needed);
a2186dfe 1631 }
26044998 1632
252b5132
RH
1633 /* And padding */
1634 if (on_page & 1)
1635 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1636}
1637
1638static void
2da42df6 1639gen_def_file (void)
252b5132
RH
1640{
1641 int i;
1642 export_type *exp;
1643
1644 inform (_("Adding exports to output file"));
26044998 1645
252b5132
RH
1646 fprintf (output_def, ";");
1647 for (i = 0; oav[i]; i++)
1648 fprintf (output_def, " %s", oav[i]);
1649
1650 fprintf (output_def, "\nEXPORTS\n");
1651
1652 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1653 {
1654 char *quote = strchr (exp->name, '.') ? "\"" : "";
1655 char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
1656
2630b4ca
DS
1657 if (res)
1658 {
2da42df6 1659 fprintf (output_def,";\t%s\n", res);
2630b4ca
DS
1660 free (res);
1661 }
1662
252b5132 1663 if (strcmp (exp->name, exp->internal_name) == 0)
26044998 1664 {
7aa52b1f 1665 fprintf (output_def, "\t%s%s%s @ %d%s%s%s\n",
252b5132
RH
1666 quote,
1667 exp->name,
1668 quote,
1669 exp->ordinal,
1670 exp->noname ? " NONAME" : "",
7aa52b1f 1671 exp->private ? "PRIVATE " : "",
2630b4ca 1672 exp->data ? " DATA" : "");
252b5132 1673 }
26044998
KH
1674 else
1675 {
7aa52b1f 1676 char * quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
252b5132 1677 /* char *alias = */
7aa52b1f 1678 fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s\n",
252b5132
RH
1679 quote,
1680 exp->name,
1681 quote,
1682 quote1,
1683 exp->internal_name,
1684 quote1,
1685 exp->ordinal,
1686 exp->noname ? " NONAME" : "",
7aa52b1f 1687 exp->private ? "PRIVATE " : "",
2630b4ca 1688 exp->data ? " DATA" : "");
252b5132 1689 }
252b5132 1690 }
26044998 1691
252b5132
RH
1692 inform (_("Added exports to output file"));
1693}
1694
1695/* generate_idata_ofile generates the portable assembly source code
1696 for the idata sections. It appends the source code to the end of
1697 the file. */
1698
1699static void
2da42df6 1700generate_idata_ofile (FILE *filvar)
252b5132
RH
1701{
1702 iheadtype *headptr;
1703 ifunctype *funcptr;
1704 int headindex;
1705 int funcindex;
1706 int nheads;
1707
1708 if (import_list == NULL)
1709 return;
1710
1711 fprintf (filvar, "%s Import data sections\n", ASM_C);
1712 fprintf (filvar, "\n\t.section\t.idata$2\n");
1713 fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1714 fprintf (filvar, "doi_idata:\n");
1715
1716 nheads = 0;
1717 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1718 {
1719 fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1720 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
1721 ASM_C, headptr->dllname);
1722 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1723 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1724 fprintf (filvar, "\t%sdllname%d%s\n",
1725 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1726 fprintf (filvar, "\t%slisttwo%d%s\n\n",
1727 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1728 nheads++;
1729 }
1730
1731 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1732 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1733 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
1734 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1735 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1736
1737 fprintf (filvar, "\n\t.section\t.idata$4\n");
1738 headindex = 0;
1739 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1740 {
1741 fprintf (filvar, "listone%d:\n", headindex);
99ad8390
NC
1742 for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
1743#ifdef DLLTOOL_MX86_64
1744 fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1745 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,ASM_LONG);
1746#else
252b5132
RH
1747 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1748 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
99ad8390
NC
1749#endif
1750#ifdef DLLTOOL_MX86_64
1751 fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */
1752#else
1753 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
1754#endif
252b5132
RH
1755 headindex++;
1756 }
1757
1758 fprintf (filvar, "\n\t.section\t.idata$5\n");
1759 headindex = 0;
1760 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1761 {
1762 fprintf (filvar, "listtwo%d:\n", headindex);
99ad8390
NC
1763 for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
1764#ifdef DLLTOOL_MX86_64
1765 fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1766 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,ASM_LONG);
1767#else
252b5132
RH
1768 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1769 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
99ad8390
NC
1770#endif
1771#ifdef DLLTOOL_MX86_64
1772 fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */
1773#else
1774 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
1775#endif
252b5132
RH
1776 headindex++;
1777 }
1778
1779 fprintf (filvar, "\n\t.section\t.idata$6\n");
1780 headindex = 0;
1781 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1782 {
1783 funcindex = 0;
1784 for (funcptr = headptr->funchead; funcptr != NULL;
1785 funcptr = funcptr->next)
1786 {
1787 fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
1788 fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
1789 ((funcptr->ord) & 0xFFFF));
1790 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name);
1791 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1792 funcindex++;
1793 }
1794 headindex++;
1795 }
1796
1797 fprintf (filvar, "\n\t.section\t.idata$7\n");
1798 headindex = 0;
1799 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1800 {
1801 fprintf (filvar,"dllname%d:\n", headindex);
1802 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
1803 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1804 headindex++;
1805 }
1806}
1807
26044998 1808/* Assemble the specified file. */
49c24507 1809static void
2da42df6 1810assemble_file (const char * source, const char * dest)
49c24507
NC
1811{
1812 char * cmd;
26044998 1813
49c24507 1814 cmd = (char *) alloca (strlen (ASM_SWITCHES) + strlen (as_flags)
96925346 1815 + strlen (source) + strlen (dest) + 50);
49c24507
NC
1816
1817 sprintf (cmd, "%s %s -o %s %s", ASM_SWITCHES, as_flags, dest, source);
1818
1819 run (as_name, cmd);
1820}
1821
252b5132 1822static void
2da42df6 1823gen_exp_file (void)
252b5132
RH
1824{
1825 FILE *f;
1826 int i;
1827 export_type *exp;
1828 dlist_type *dl;
1829
1830 /* xgettext:c-format */
37cc8ec1 1831 inform (_("Generating export file: %s"), exp_name);
26044998 1832
252b5132
RH
1833 f = fopen (TMP_ASM, FOPEN_WT);
1834 if (!f)
1835 /* xgettext:c-format */
1836 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
26044998 1837
252b5132
RH
1838 /* xgettext:c-format */
1839 inform (_("Opened temporary file: %s"), TMP_ASM);
1840
1841 dump_def_info (f);
26044998 1842
252b5132
RH
1843 if (d_exports)
1844 {
1845 fprintf (f, "\t.section .edata\n\n");
1846 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
0af1713e
AM
1847 fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG,
1848 (unsigned long) time(0), ASM_C);
252b5132
RH
1849 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
1850 fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1851 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
1852
1853
1854 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
1855 fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
1856 ASM_C,
1857 d_named_nfuncs, d_low_ord, d_high_ord);
1858 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
1859 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
1860 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1861
1862 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
1863 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1864
1865 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1866
1867 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
1868
1869
1870 fprintf(f,"%s Export address Table\n", ASM_C);
1871 fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
1872 fprintf (f, "afuncs:\n");
1873 i = d_low_ord;
1874
1875 for (exp = d_exports; exp; exp = exp->next)
1876 {
1877 if (exp->ordinal != i)
1878 {
252b5132
RH
1879 while (i < exp->ordinal)
1880 {
1881 fprintf(f,"\t%s\t0\n", ASM_LONG);
1882 i++;
1883 }
1884 }
04847a4d
CF
1885
1886 if (exp->forward == 0)
c9e38879
NC
1887 {
1888 if (exp->internal_name[0] == '@')
1889 fprintf (f, "\t%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
1890 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1891 else
1892 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
2758961a 1893 ASM_PREFIX (exp->internal_name),
c9e38879
NC
1894 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1895 }
04847a4d
CF
1896 else
1897 fprintf (f, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE,
1898 exp->forward, ASM_RVA_AFTER, ASM_C, exp->ordinal);
252b5132
RH
1899 i++;
1900 }
1901
1902 fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
1903 fprintf (f, "anames:\n");
1904
1905 for (i = 0; (exp = d_exports_lexically[i]); i++)
1906 {
1907 if (!exp->noname || show_allnames)
1908 fprintf (f, "\t%sn%d%s\n",
1909 ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
1910 }
1911
ea6e992c 1912 fprintf (f,"%s Export Ordinal Table\n", ASM_C);
252b5132
RH
1913 fprintf (f, "anords:\n");
1914 for (i = 0; (exp = d_exports_lexically[i]); i++)
1915 {
1916 if (!exp->noname || show_allnames)
1917 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
1918 }
1919
1920 fprintf(f,"%s Export Name Table\n", ASM_C);
1921 for (i = 0; (exp = d_exports_lexically[i]); i++)
eff21b8e
CF
1922 {
1923 if (!exp->noname || show_allnames)
04847a4d 1924 fprintf (f, "n%d: %s \"%s\"\n",
f3f7fbb2 1925 exp->ordinal, ASM_TEXT, xlate (exp->name));
eff21b8e
CF
1926 if (exp->forward != 0)
1927 fprintf (f, "f%d: %s \"%s\"\n",
1928 exp->forward, ASM_TEXT, exp->internal_name);
1929 }
252b5132
RH
1930
1931 if (a_list)
1932 {
661016bb 1933 fprintf (f, "\t.section %s\n", DRECTVE_SECTION_NAME);
252b5132
RH
1934 for (dl = a_list; dl; dl = dl->next)
1935 {
1936 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1937 }
1938 }
26044998 1939
252b5132
RH
1940 if (d_list)
1941 {
1942 fprintf (f, "\t.section .rdata\n");
1943 for (dl = d_list; dl; dl = dl->next)
1944 {
1945 char *p;
1946 int l;
26044998 1947
5f0f29c3
NC
1948 /* We don't output as ascii because there can
1949 be quote characters in the string. */
252b5132
RH
1950 l = 0;
1951 for (p = dl->text; *p; p++)
1952 {
1953 if (l == 0)
1954 fprintf (f, "\t%s\t", ASM_BYTE);
1955 else
1956 fprintf (f, ",");
1957 fprintf (f, "%d", *p);
1958 if (p[1] == 0)
1959 {
1960 fprintf (f, ",0\n");
1961 break;
1962 }
1963 if (++l == 10)
1964 {
1965 fprintf (f, "\n");
1966 l = 0;
1967 }
1968 }
1969 }
1970 }
1971 }
1972
1973
1974 /* Add to the output file a way of getting to the exported names
5f0f29c3 1975 without using the import library. */
252b5132
RH
1976 if (add_indirect)
1977 {
1978 fprintf (f, "\t.section\t.rdata\n");
1979 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1980 if (!exp->noname || show_allnames)
1981 {
1982 /* We use a single underscore for MS compatibility, and a
1983 double underscore for backward compatibility with old
1984 cygwin releases. */
5f0f29c3
NC
1985 if (create_compat_implib)
1986 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
252b5132 1987 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
5f0f29c3
NC
1988 if (create_compat_implib)
1989 fprintf (f, "__imp_%s:\n", exp->name);
252b5132
RH
1990 fprintf (f, "_imp__%s:\n", exp->name);
1991 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1992 }
1993 }
1994
c9e38879 1995 /* Dump the reloc section if a base file is provided. */
252b5132
RH
1996 if (base_file)
1997 {
d078078d
KT
1998 bfd_vma addr;
1999 bfd_vma need[PAGE_SIZE];
2000 bfd_vma page_addr;
252b5132
RH
2001 int numbytes;
2002 int num_entries;
d078078d 2003 bfd_vma *copy;
252b5132
RH
2004 int j;
2005 int on_page;
2006 fprintf (f, "\t.section\t.init\n");
2007 fprintf (f, "lab:\n");
2008
2009 fseek (base_file, 0, SEEK_END);
2010 numbytes = ftell (base_file);
2011 fseek (base_file, 0, SEEK_SET);
2012 copy = xmalloc (numbytes);
2013 fread (copy, 1, numbytes, base_file);
d078078d 2014 num_entries = numbytes / sizeof (bfd_vma);
252b5132
RH
2015
2016
2017 fprintf (f, "\t.section\t.reloc\n");
2018 if (num_entries)
2019 {
2020 int src;
2021 int dst = 0;
d078078d
KT
2022 bfd_vma last = (bfd_vma) -1;
2023 qsort (copy, num_entries, sizeof (bfd_vma), sfunc);
50c2245b 2024 /* Delete duplicates */
252b5132
RH
2025 for (src = 0; src < num_entries; src++)
2026 {
2027 if (last != copy[src])
2028 last = copy[dst++] = copy[src];
2029 }
2030 num_entries = dst;
2031 addr = copy[0];
2032 page_addr = addr & PAGE_MASK; /* work out the page addr */
2033 on_page = 0;
2034 for (j = 0; j < num_entries; j++)
2035 {
252b5132
RH
2036 addr = copy[j];
2037 if ((addr & PAGE_MASK) != page_addr)
2038 {
252b5132
RH
2039 flush_page (f, need, page_addr, on_page);
2040 on_page = 0;
2041 page_addr = addr & PAGE_MASK;
2042 }
2043 need[on_page++] = addr;
2044 }
252b5132
RH
2045 flush_page (f, need, page_addr, on_page);
2046
d8bcc1ac 2047/* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
252b5132
RH
2048 }
2049 }
2050
2051 generate_idata_ofile (f);
2052
2053 fclose (f);
2054
c9e38879 2055 /* Assemble the file. */
49c24507 2056 assemble_file (TMP_ASM, exp_name);
bb0cb4db 2057
252b5132
RH
2058 if (dontdeltemps == 0)
2059 unlink (TMP_ASM);
26044998 2060
252b5132
RH
2061 inform (_("Generated exports file"));
2062}
2063
2064static const char *
2da42df6 2065xlate (const char *name)
252b5132 2066{
c9e38879
NC
2067 int lead_at = (*name == '@');
2068
14288fdc
DS
2069 if (!lead_at && (add_underscore
2070 || (add_stdcall_underscore
2071 && strchr (name, '@'))))
252b5132
RH
2072 {
2073 char *copy = xmalloc (strlen (name) + 2);
c9e38879 2074
252b5132
RH
2075 copy[0] = '_';
2076 strcpy (copy + 1, name);
2077 name = copy;
2078 }
2079
2080 if (killat)
2081 {
2082 char *p;
c9e38879
NC
2083
2084 name += lead_at;
252b5132
RH
2085 p = strchr (name, '@');
2086 if (p)
2087 *p = 0;
2088 }
2089 return name;
2090}
2091
252b5132
RH
2092typedef struct
2093{
2094 int id;
2095 const char *name;
2096 int flags;
2097 int align;
2098 asection *sec;
2099 asymbol *sym;
2100 asymbol **sympp;
2101 int size;
c9e38879 2102 unsigned char *data;
252b5132
RH
2103} sinfo;
2104
2105#ifndef DLLTOOL_PPC
2106
2107#define TEXT 0
2108#define DATA 1
2109#define BSS 2
2110#define IDATA7 3
2111#define IDATA5 4
2112#define IDATA4 5
2113#define IDATA6 6
2114
2115#define NSECS 7
2116
bee72332
DD
2117#define TEXT_SEC_FLAGS \
2118 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS)
2119#define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA)
2120#define BSS_SEC_FLAGS SEC_ALLOC
2121
2122#define INIT_SEC_DATA(id, name, flags, align) \
2123 { id, name, flags, align, NULL, NULL, NULL, 0, NULL }
252b5132
RH
2124static sinfo secdata[NSECS] =
2125{
bee72332
DD
2126 INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2),
2127 INIT_SEC_DATA (DATA, ".data", DATA_SEC_FLAGS, 2),
2128 INIT_SEC_DATA (BSS, ".bss", BSS_SEC_FLAGS, 2),
2129 INIT_SEC_DATA (IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2),
2130 INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2),
2131 INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2),
2132 INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1)
252b5132
RH
2133};
2134
2135#else
2136
c9e38879
NC
2137/* Sections numbered to make the order the same as other PowerPC NT
2138 compilers. This also keeps funny alignment thingies from happening. */
252b5132
RH
2139#define TEXT 0
2140#define PDATA 1
2141#define RDATA 2
2142#define IDATA5 3
2143#define IDATA4 4
2144#define IDATA6 5
2145#define IDATA7 6
2146#define DATA 7
2147#define BSS 8
2148
2149#define NSECS 9
2150
2151static sinfo secdata[NSECS] =
2152{
2153 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
2154 { PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
2155 { RDATA, ".reldata", SEC_HAS_CONTENTS, 2},
2156 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
2157 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
2158 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1},
2159 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
2160 { DATA, ".data", SEC_DATA, 2},
2161 { BSS, ".bss", 0, 2}
2162};
2163
2164#endif
2165
c9e38879
NC
2166/* This is what we're trying to make. We generate the imp symbols with
2167 both single and double underscores, for compatibility.
252b5132
RH
2168
2169 .text
2170 .global _GetFileVersionInfoSizeW@8
2171 .global __imp_GetFileVersionInfoSizeW@8
2172_GetFileVersionInfoSizeW@8:
2173 jmp * __imp_GetFileVersionInfoSizeW@8
2174 .section .idata$7 # To force loading of head
2175 .long __version_a_head
2176# Import Address Table
2177 .section .idata$5
2178__imp_GetFileVersionInfoSizeW@8:
2179 .rva ID2
2180
2181# Import Lookup Table
2182 .section .idata$4
2183 .rva ID2
2184# Hint/Name table
2185 .section .idata$6
2186ID2: .short 2
2187 .asciz "GetFileVersionInfoSizeW"
2188
2189
c9e38879 2190 For the PowerPC, here's the variation on the above scheme:
252b5132
RH
2191
2192# Rather than a simple "jmp *", the code to get to the dll function
2193# looks like:
2194 .text
2195 lwz r11,[tocv]__imp_function_name(r2)
2196# RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2197 lwz r12,0(r11)
2198 stw r2,4(r1)
2199 mtctr r12
2200 lwz r2,4(r11)
c9e38879 2201 bctr */
252b5132
RH
2202
2203static char *
2da42df6 2204make_label (const char *prefix, const char *name)
252b5132 2205{
2758961a
NC
2206 int len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2207 char *copy = xmalloc (len + 1);
c9e38879 2208
2758961a 2209 strcpy (copy, ASM_PREFIX (name));
252b5132
RH
2210 strcat (copy, prefix);
2211 strcat (copy, name);
2212 return copy;
2213}
2214
c9e38879 2215static char *
2da42df6 2216make_imp_label (const char *prefix, const char *name)
c9e38879
NC
2217{
2218 int len;
2219 char *copy;
2220
2221 if (name[0] == '@')
2222 {
2223 len = strlen (prefix) + strlen (name);
2224 copy = xmalloc (len + 1);
2225 strcpy (copy, prefix);
2226 strcat (copy, name);
2227 }
2228 else
2229 {
2758961a 2230 len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
c9e38879
NC
2231 copy = xmalloc (len + 1);
2232 strcpy (copy, prefix);
2758961a 2233 strcat (copy, ASM_PREFIX (name));
c9e38879
NC
2234 strcat (copy, name);
2235 }
2236 return copy;
2237}
2238
252b5132 2239static bfd *
2da42df6 2240make_one_lib_file (export_type *exp, int i)
252b5132 2241{
84e43642
BE
2242 bfd * abfd;
2243 asymbol * exp_label;
2244 asymbol * iname = 0;
2245 asymbol * iname2;
2246 asymbol * iname_lab;
2247 asymbol ** iname_lab_pp;
2248 asymbol ** iname_pp;
252b5132 2249#ifdef DLLTOOL_PPC
84e43642
BE
2250 asymbol ** fn_pp;
2251 asymbol ** toc_pp;
252b5132
RH
2252#define EXTRA 2
2253#endif
2254#ifndef EXTRA
2255#define EXTRA 0
2256#endif
84e43642
BE
2257 asymbol * ptrs[NSECS + 4 + EXTRA + 1];
2258 flagword applicable;
2259 char * outname = xmalloc (strlen (TMP_STUB) + 10);
2260 int oidx = 0;
252b5132 2261
26044998 2262
84e43642 2263 sprintf (outname, "%s%05d.o", TMP_STUB, i);
26044998 2264
84e43642 2265 abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET);
26044998 2266
84e43642
BE
2267 if (!abfd)
2268 /* xgettext:c-format */
2269 fatal (_("bfd_open failed open stub file: %s"), outname);
252b5132 2270
84e43642
BE
2271 /* xgettext:c-format */
2272 inform (_("Creating stub file: %s"), outname);
26044998 2273
84e43642
BE
2274 bfd_set_format (abfd, bfd_object);
2275 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
252b5132
RH
2276
2277#ifdef DLLTOOL_ARM
84e43642
BE
2278 if (machine == MARM_INTERWORK || machine == MTHUMB)
2279 bfd_set_private_flags (abfd, F_INTERWORK);
252b5132 2280#endif
26044998 2281
84e43642 2282 applicable = bfd_applicable_section_flags (abfd);
26044998 2283
84e43642
BE
2284 /* First make symbols for the sections. */
2285 for (i = 0; i < NSECS; i++)
2286 {
2287 sinfo *si = secdata + i;
2288
2289 if (si->id != i)
2290 abort();
2291 si->sec = bfd_make_section_old_way (abfd, si->name);
2292 bfd_set_section_flags (abfd,
2293 si->sec,
2294 si->flags & applicable);
2295
2296 bfd_set_section_alignment(abfd, si->sec, si->align);
2297 si->sec->output_section = si->sec;
2298 si->sym = bfd_make_empty_symbol(abfd);
2299 si->sym->name = si->sec->name;
2300 si->sym->section = si->sec;
2301 si->sym->flags = BSF_LOCAL;
2302 si->sym->value = 0;
2303 ptrs[oidx] = si->sym;
2304 si->sympp = ptrs + oidx;
2305 si->size = 0;
2306 si->data = NULL;
2307
2308 oidx++;
2309 }
252b5132 2310
84e43642
BE
2311 if (! exp->data)
2312 {
2313 exp_label = bfd_make_empty_symbol (abfd);
2314 exp_label->name = make_imp_label ("", exp->name);
252b5132 2315
84e43642
BE
2316 /* On PowerPC, the function name points to a descriptor in
2317 the rdata section, the first element of which is a
2318 pointer to the code (..function_name), and the second
2319 points to the .toc. */
252b5132 2320#ifdef DLLTOOL_PPC
84e43642
BE
2321 if (machine == MPPC)
2322 exp_label->section = secdata[RDATA].sec;
2323 else
252b5132 2324#endif
84e43642 2325 exp_label->section = secdata[TEXT].sec;
252b5132 2326
84e43642
BE
2327 exp_label->flags = BSF_GLOBAL;
2328 exp_label->value = 0;
252b5132
RH
2329
2330#ifdef DLLTOOL_ARM
84e43642
BE
2331 if (machine == MTHUMB)
2332 bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
252b5132 2333#endif
84e43642
BE
2334 ptrs[oidx++] = exp_label;
2335 }
252b5132 2336
84e43642
BE
2337 /* Generate imp symbols with one underscore for Microsoft
2338 compatibility, and with two underscores for backward
2339 compatibility with old versions of cygwin. */
2340 if (create_compat_implib)
2341 {
2342 iname = bfd_make_empty_symbol (abfd);
2343 iname->name = make_imp_label ("___imp", exp->name);
2344 iname->section = secdata[IDATA5].sec;
2345 iname->flags = BSF_GLOBAL;
2346 iname->value = 0;
2347 }
252b5132 2348
84e43642
BE
2349 iname2 = bfd_make_empty_symbol (abfd);
2350 iname2->name = make_imp_label ("__imp_", exp->name);
2351 iname2->section = secdata[IDATA5].sec;
2352 iname2->flags = BSF_GLOBAL;
2353 iname2->value = 0;
252b5132 2354
84e43642 2355 iname_lab = bfd_make_empty_symbol (abfd);
252b5132 2356
84e43642
BE
2357 iname_lab->name = head_label;
2358 iname_lab->section = (asection *) &bfd_und_section;
2359 iname_lab->flags = 0;
2360 iname_lab->value = 0;
252b5132 2361
84e43642
BE
2362 iname_pp = ptrs + oidx;
2363 if (create_compat_implib)
2364 ptrs[oidx++] = iname;
2365 ptrs[oidx++] = iname2;
252b5132 2366
84e43642
BE
2367 iname_lab_pp = ptrs + oidx;
2368 ptrs[oidx++] = iname_lab;
252b5132
RH
2369
2370#ifdef DLLTOOL_PPC
84e43642
BE
2371 /* The symbol referring to the code (.text). */
2372 {
2373 asymbol *function_name;
252b5132 2374
84e43642
BE
2375 function_name = bfd_make_empty_symbol(abfd);
2376 function_name->name = make_label ("..", exp->name);
2377 function_name->section = secdata[TEXT].sec;
2378 function_name->flags = BSF_GLOBAL;
2379 function_name->value = 0;
252b5132 2380
84e43642
BE
2381 fn_pp = ptrs + oidx;
2382 ptrs[oidx++] = function_name;
2383 }
252b5132 2384
84e43642
BE
2385 /* The .toc symbol. */
2386 {
2387 asymbol *toc_symbol;
252b5132 2388
84e43642
BE
2389 toc_symbol = bfd_make_empty_symbol (abfd);
2390 toc_symbol->name = make_label (".", "toc");
2391 toc_symbol->section = (asection *)&bfd_und_section;
2392 toc_symbol->flags = BSF_GLOBAL;
2393 toc_symbol->value = 0;
252b5132 2394
84e43642
BE
2395 toc_pp = ptrs + oidx;
2396 ptrs[oidx++] = toc_symbol;
2397 }
252b5132 2398#endif
26044998 2399
84e43642 2400 ptrs[oidx] = 0;
252b5132 2401
84e43642
BE
2402 for (i = 0; i < NSECS; i++)
2403 {
2404 sinfo *si = secdata + i;
2405 asection *sec = si->sec;
2406 arelent *rel;
2407 arelent **rpp;
252b5132 2408
84e43642
BE
2409 switch (i)
2410 {
2411 case TEXT:
2412 if (! exp->data)
252b5132 2413 {
84e43642
BE
2414 si->size = HOW_JTAB_SIZE;
2415 si->data = xmalloc (HOW_JTAB_SIZE);
2416 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
26044998 2417
99ad8390 2418 /* Add the reloc into idata$5. */
84e43642 2419 rel = xmalloc (sizeof (arelent));
252b5132 2420
84e43642
BE
2421 rpp = xmalloc (sizeof (arelent *) * 2);
2422 rpp[0] = rel;
2423 rpp[1] = 0;
252b5132 2424
84e43642
BE
2425 rel->address = HOW_JTAB_ROFF;
2426 rel->addend = 0;
252b5132 2427
84e43642 2428 if (machine == MPPC)
252b5132 2429 {
84e43642
BE
2430 rel->howto = bfd_reloc_type_lookup (abfd,
2431 BFD_RELOC_16_GOTOFF);
2432 rel->sym_ptr_ptr = iname_pp;
591a748a
NC
2433 }
2434 else if (machine == MX86)
2435 {
2436 rel->howto = bfd_reloc_type_lookup (abfd,
2437 BFD_RELOC_32_PCREL);
2438 rel->sym_ptr_ptr = iname_pp;
252b5132
RH
2439 }
2440 else
2441 {
84e43642
BE
2442 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2443 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
252b5132 2444 }
84e43642
BE
2445 sec->orelocation = rpp;
2446 sec->reloc_count = 1;
2447 }
2448 break;
2449 case IDATA4:
2450 case IDATA5:
2451 /* An idata$4 or idata$5 is one word long, and has an
2452 rva to idata$6. */
252b5132 2453
99ad8390
NC
2454#ifdef DLLTOOL_MX86_64
2455 si->data = xmalloc (8);
2456 si->size = 8;
2457
2458 if (exp->noname)
2459 {
2460 si->data[0] = exp->ordinal ;
2461 si->data[1] = exp->ordinal >> 8;
2462 si->data[2] = exp->ordinal >> 16;
2463 si->data[3] = exp->ordinal >> 24;
2464 si->data[4] = 0;
2465 si->data[5] = 0;
2466 si->data[6] = 0;
2467 si->data[7] = 0x80;
2468 }
2469 else
2470 {
2471 sec->reloc_count = 1;
2472 memset (si->data, 0, si->size);
2473 rel = xmalloc (sizeof (arelent));
2474 rpp = xmalloc (sizeof (arelent *) * 2);
2475 rpp[0] = rel;
2476 rpp[1] = 0;
2477 rel->address = 0;
2478 rel->addend = 0;
2479 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2480 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2481 sec->orelocation = rpp;
2482 }
2483#else
84e43642
BE
2484 si->data = xmalloc (4);
2485 si->size = 4;
252b5132 2486
84e43642
BE
2487 if (exp->noname)
2488 {
2489 si->data[0] = exp->ordinal ;
2490 si->data[1] = exp->ordinal >> 8;
2491 si->data[2] = exp->ordinal >> 16;
2492 si->data[3] = 0x80;
2493 }
2494 else
2495 {
2496 sec->reloc_count = 1;
252b5132
RH
2497 memset (si->data, 0, si->size);
2498 rel = xmalloc (sizeof (arelent));
2499 rpp = xmalloc (sizeof (arelent *) * 2);
2500 rpp[0] = rel;
84e43642 2501 rpp[1] = 0;
252b5132
RH
2502 rel->address = 0;
2503 rel->addend = 0;
2504 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
84e43642 2505 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
252b5132 2506 sec->orelocation = rpp;
84e43642 2507 }
99ad8390 2508#endif
84e43642 2509 break;
252b5132 2510
84e43642
BE
2511 case IDATA6:
2512 if (!exp->noname)
2513 {
2514 /* This used to add 1 to exp->hint. I don't know
2515 why it did that, and it does not match what I see
2516 in programs compiled with the MS tools. */
2517 int idx = exp->hint;
2518 si->size = strlen (xlate (exp->import_name)) + 3;
2519 si->data = xmalloc (si->size);
2520 si->data[0] = idx & 0xff;
2521 si->data[1] = idx >> 8;
9210d879 2522 strcpy ((char *) si->data + 2, xlate (exp->import_name));
84e43642
BE
2523 }
2524 break;
2525 case IDATA7:
2526 si->size = 4;
2527 si->data = xmalloc (4);
2528 memset (si->data, 0, si->size);
2529 rel = xmalloc (sizeof (arelent));
2530 rpp = xmalloc (sizeof (arelent *) * 2);
2531 rpp[0] = rel;
2532 rel->address = 0;
2533 rel->addend = 0;
2534 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2535 rel->sym_ptr_ptr = iname_lab_pp;
2536 sec->orelocation = rpp;
2537 sec->reloc_count = 1;
2538 break;
252b5132 2539
84e43642
BE
2540#ifdef DLLTOOL_PPC
2541 case PDATA:
2542 {
2543 /* The .pdata section is 5 words long.
2544 Think of it as:
2545 struct
2546 {
2547 bfd_vma BeginAddress, [0x00]
2548 EndAddress, [0x04]
2549 ExceptionHandler, [0x08]
2550 HandlerData, [0x0c]
2551 PrologEndAddress; [0x10]
2552 }; */
2553
2554 /* So this pdata section setups up this as a glue linkage to
2555 a dll routine. There are a number of house keeping things
2556 we need to do:
2557
2558 1. In the name of glue trickery, the ADDR32 relocs for 0,
2559 4, and 0x10 are set to point to the same place:
2560 "..function_name".
2561 2. There is one more reloc needed in the pdata section.
2562 The actual glue instruction to restore the toc on
2563 return is saved as the offset in an IMGLUE reloc.
2564 So we need a total of four relocs for this section.
2565
2566 3. Lastly, the HandlerData field is set to 0x03, to indicate
2567 that this is a glue routine. */
2568 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
2569
2570 /* Alignment must be set to 2**2 or you get extra stuff. */
2571 bfd_set_section_alignment(abfd, sec, 2);
2572
2573 si->size = 4 * 5;
2574 si->data = xmalloc (si->size);
2575 memset (si->data, 0, si->size);
2576 rpp = xmalloc (sizeof (arelent *) * 5);
2577 rpp[0] = imglue = xmalloc (sizeof (arelent));
2578 rpp[1] = ba_rel = xmalloc (sizeof (arelent));
2579 rpp[2] = ea_rel = xmalloc (sizeof (arelent));
2580 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
2581 rpp[4] = 0;
2582
2583 /* Stick the toc reload instruction in the glue reloc. */
2584 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
2585
2586 imglue->addend = 0;
2587 imglue->howto = bfd_reloc_type_lookup (abfd,
2588 BFD_RELOC_32_GOTOFF);
2589 imglue->sym_ptr_ptr = fn_pp;
2590
2591 ba_rel->address = 0;
2592 ba_rel->addend = 0;
2593 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2594 ba_rel->sym_ptr_ptr = fn_pp;
2595
2596 bfd_put_32 (abfd, 0x18, si->data + 0x04);
2597 ea_rel->address = 4;
2598 ea_rel->addend = 0;
2599 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2600 ea_rel->sym_ptr_ptr = fn_pp;
2601
2602 /* Mark it as glue. */
2603 bfd_put_32 (abfd, 0x03, si->data + 0x0c);
2604
2605 /* Mark the prolog end address. */
2606 bfd_put_32 (abfd, 0x0D, si->data + 0x10);
2607 pea_rel->address = 0x10;
2608 pea_rel->addend = 0;
2609 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2610 pea_rel->sym_ptr_ptr = fn_pp;
2611
2612 sec->orelocation = rpp;
2613 sec->reloc_count = 4;
2614 break;
2615 }
2616 case RDATA:
2617 /* Each external function in a PowerPC PE file has a two word
2618 descriptor consisting of:
2619 1. The address of the code.
2620 2. The address of the appropriate .toc
2621 We use relocs to build this. */
2622 si->size = 8;
2623 si->data = xmalloc (8);
2624 memset (si->data, 0, si->size);
2625
2626 rpp = xmalloc (sizeof (arelent *) * 3);
2627 rpp[0] = rel = xmalloc (sizeof (arelent));
2628 rpp[1] = xmalloc (sizeof (arelent));
2629 rpp[2] = 0;
2630
2631 rel->address = 0;
2632 rel->addend = 0;
2633 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2634 rel->sym_ptr_ptr = fn_pp;
2635
2636 rel = rpp[1];
2637
2638 rel->address = 4;
2639 rel->addend = 0;
2640 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2641 rel->sym_ptr_ptr = toc_pp;
2642
2643 sec->orelocation = rpp;
2644 sec->reloc_count = 2;
2645 break;
252b5132 2646#endif /* DLLTOOL_PPC */
252b5132 2647 }
84e43642 2648 }
252b5132 2649
84e43642
BE
2650 {
2651 bfd_vma vma = 0;
2652 /* Size up all the sections. */
2653 for (i = 0; i < NSECS; i++)
252b5132 2654 {
84e43642 2655 sinfo *si = secdata + i;
252b5132 2656
84e43642
BE
2657 bfd_set_section_size (abfd, si->sec, si->size);
2658 bfd_set_section_vma (abfd, si->sec, vma);
252b5132 2659 }
84e43642
BE
2660 }
2661 /* Write them out. */
2662 for (i = 0; i < NSECS; i++)
2663 {
2664 sinfo *si = secdata + i;
252b5132 2665
84e43642
BE
2666 if (i == IDATA5 && no_idata5)
2667 continue;
252b5132 2668
84e43642
BE
2669 if (i == IDATA4 && no_idata4)
2670 continue;
252b5132 2671
84e43642
BE
2672 bfd_set_section_contents (abfd, si->sec,
2673 si->data, 0,
2674 si->size);
252b5132 2675 }
84e43642
BE
2676
2677 bfd_set_symtab (abfd, ptrs, oidx);
2678 bfd_close (abfd);
2679 abfd = bfd_openr (outname, HOW_BFD_READ_TARGET);
2680 return abfd;
252b5132
RH
2681}
2682
2683static bfd *
2da42df6 2684make_head (void)
252b5132 2685{
bb0cb4db 2686 FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
252b5132 2687
661016bb
NC
2688 if (f == NULL)
2689 {
2690 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2691 return NULL;
2692 }
26044998 2693
252b5132
RH
2694 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2695 fprintf (f, "\t.section .idata$2\n");
2696
2697 fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
2698
2699 fprintf (f, "%s:\n", head_label);
2700
2701 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2702 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2703
2704 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2705 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2706 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2707 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2708 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2709 ASM_RVA_BEFORE,
2710 imp_name_lab,
2711 ASM_RVA_AFTER,
2712 ASM_C);
2713 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2714 ASM_RVA_BEFORE,
2715 ASM_RVA_AFTER, ASM_C);
2716
2717 fprintf (f, "%sStuff for compatibility\n", ASM_C);
2718
2719 if (!no_idata5)
2720 {
2721 fprintf (f, "\t.section\t.idata$5\n");
99ad8390
NC
2722#ifdef DLLTOOL_MX86_64
2723 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */
2724#else
2725 fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
2726#endif
252b5132
RH
2727 fprintf (f, "fthunk:\n");
2728 }
26044998 2729
252b5132
RH
2730 if (!no_idata4)
2731 {
2732 fprintf (f, "\t.section\t.idata$4\n");
252b5132
RH
2733 fprintf (f, "\t%s\t0\n", ASM_LONG);
2734 fprintf (f, "\t.section .idata$4\n");
2735 fprintf (f, "hname:\n");
2736 }
26044998 2737
252b5132
RH
2738 fclose (f);
2739
49c24507 2740 assemble_file (TMP_HEAD_S, TMP_HEAD_O);
252b5132 2741
49c24507 2742 return bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
252b5132
RH
2743}
2744
2745static bfd *
2da42df6 2746make_tail (void)
252b5132 2747{
bb0cb4db 2748 FILE *f = fopen (TMP_TAIL_S, FOPEN_WT);
252b5132 2749
661016bb
NC
2750 if (f == NULL)
2751 {
2752 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S);
2753 return NULL;
2754 }
26044998 2755
252b5132
RH
2756 if (!no_idata4)
2757 {
2758 fprintf (f, "\t.section .idata$4\n");
99ad8390
NC
2759#ifdef DLLTOOL_MX86_64
2760 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */
2761#else
2762 fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
2763#endif
252b5132 2764 }
26044998 2765
252b5132
RH
2766 if (!no_idata5)
2767 {
2768 fprintf (f, "\t.section .idata$5\n");
99ad8390
NC
2769#ifdef DLLTOOL_MX86_64
2770 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */
2771#else
2772 fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
2773#endif
252b5132
RH
2774 }
2775
2776#ifdef DLLTOOL_PPC
2777 /* Normally, we need to see a null descriptor built in idata$3 to
2778 act as the terminator for the list. The ideal way, I suppose,
2779 would be to mark this section as a comdat type 2 section, so
2780 only one would appear in the final .exe (if our linker supported
2781 comdat, that is) or cause it to be inserted by something else (say
c9e38879 2782 crt0). */
252b5132
RH
2783
2784 fprintf (f, "\t.section .idata$3\n");
2785 fprintf (f, "\t%s\t0\n", ASM_LONG);
2786 fprintf (f, "\t%s\t0\n", ASM_LONG);
2787 fprintf (f, "\t%s\t0\n", ASM_LONG);
2788 fprintf (f, "\t%s\t0\n", ASM_LONG);
2789 fprintf (f, "\t%s\t0\n", ASM_LONG);
2790#endif
2791
2792#ifdef DLLTOOL_PPC
2793 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
c9e38879 2794 do too. Original, huh? */
252b5132
RH
2795 fprintf (f, "\t.section .idata$6\n");
2796#else
2797 fprintf (f, "\t.section .idata$7\n");
2798#endif
2799
2800 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
2801 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
2802 imp_name_lab, ASM_TEXT, dll_name);
2803
2804 fclose (f);
2805
49c24507 2806 assemble_file (TMP_TAIL_S, TMP_TAIL_O);
26044998 2807
c9e38879 2808 return bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET);
252b5132
RH
2809}
2810
2811static void
2da42df6 2812gen_lib_file (void)
252b5132
RH
2813{
2814 int i;
2815 export_type *exp;
2816 bfd *ar_head;
2817 bfd *ar_tail;
2818 bfd *outarch;
2819 bfd * head = 0;
2820
2821 unlink (imp_name);
2822
49c24507 2823 outarch = bfd_openw (imp_name, HOW_BFD_WRITE_TARGET);
252b5132
RH
2824
2825 if (!outarch)
2826 /* xgettext:c-format */
2827 fatal (_("Can't open .lib file: %s"), imp_name);
2828
2829 /* xgettext:c-format */
37cc8ec1 2830 inform (_("Creating library file: %s"), imp_name);
26044998 2831
252b5132
RH
2832 bfd_set_format (outarch, bfd_archive);
2833 outarch->has_armap = 1;
a8da6403 2834 outarch->is_thin_archive = 0;
252b5132 2835
26044998 2836 /* Work out a reasonable size of things to put onto one line. */
252b5132
RH
2837 ar_head = make_head ();
2838 ar_tail = make_tail();
2839
2840 if (ar_head == NULL || ar_tail == NULL)
2841 return;
26044998 2842
252b5132
RH
2843 for (i = 0; (exp = d_exports_lexically[i]); i++)
2844 {
7aa52b1f
NC
2845 bfd *n;
2846 /* Don't add PRIVATE entries to import lib. */
2847 if (exp->private)
2848 continue;
2849 n = make_one_lib_file (exp, i);
cc481421 2850 n->archive_next = head;
252b5132 2851 head = n;
0fd555c4
NC
2852 if (ext_prefix_alias)
2853 {
2854 export_type alias_exp;
2855
2856 assert (i < PREFIX_ALIAS_BASE);
2857 alias_exp.name = make_imp_label (ext_prefix_alias, exp->name);
2858 alias_exp.internal_name = exp->internal_name;
2859 alias_exp.import_name = exp->name;
2860 alias_exp.ordinal = exp->ordinal;
2861 alias_exp.constant = exp->constant;
2862 alias_exp.noname = exp->noname;
2863 alias_exp.private = exp->private;
2864 alias_exp.data = exp->data;
2865 alias_exp.hint = exp->hint;
2866 alias_exp.forward = exp->forward;
2867 alias_exp.next = exp->next;
2868 n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE);
cc481421 2869 n->archive_next = head;
0fd555c4
NC
2870 head = n;
2871 }
252b5132
RH
2872 }
2873
c9e38879 2874 /* Now stick them all into the archive. */
cc481421
AM
2875 ar_head->archive_next = head;
2876 ar_tail->archive_next = ar_head;
252b5132
RH
2877 head = ar_tail;
2878
2879 if (! bfd_set_archive_head (outarch, head))
2880 bfd_fatal ("bfd_set_archive_head");
26044998 2881
252b5132
RH
2882 if (! bfd_close (outarch))
2883 bfd_fatal (imp_name);
2884
2885 while (head != NULL)
2886 {
cc481421 2887 bfd *n = head->archive_next;
252b5132
RH
2888 bfd_close (head);
2889 head = n;
2890 }
2891
c9e38879 2892 /* Delete all the temp files. */
252b5132
RH
2893 if (dontdeltemps == 0)
2894 {
2895 unlink (TMP_HEAD_O);
2896 unlink (TMP_HEAD_S);
2897 unlink (TMP_TAIL_O);
2898 unlink (TMP_TAIL_S);
2899 }
2900
2901 if (dontdeltemps < 2)
2902 {
bb0cb4db
ILT
2903 char *name;
2904
bf7a6389 2905 name = (char *) alloca (strlen (TMP_STUB) + 10);
7aa52b1f 2906 for (i = 0; (exp = d_exports_lexically[i]); i++)
252b5132 2907 {
7aa52b1f
NC
2908 /* Don't delete non-existent stubs for PRIVATE entries. */
2909 if (exp->private)
2910 continue;
bb0cb4db
ILT
2911 sprintf (name, "%s%05d.o", TMP_STUB, i);
2912 if (unlink (name) < 0)
252b5132 2913 /* xgettext:c-format */
37cc8ec1 2914 non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
0fd555c4
NC
2915 if (ext_prefix_alias)
2916 {
2917 sprintf (name, "%s%05d.o", TMP_STUB, i + PREFIX_ALIAS_BASE);
2918 if (unlink (name) < 0)
2919 /* xgettext:c-format */
2920 non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
2921 }
252b5132
RH
2922 }
2923 }
26044998 2924
252b5132
RH
2925 inform (_("Created lib file"));
2926}
2927
d4732f7c
CW
2928/* identify_dll_for_implib
2929
2930 This is the main implementation for the --identify option.
2931 Given the name of an import library in identify_imp_name,
2932 search all archive members for an .idata$7 section
2933 (.idata$6 on PPC). This section will consist of a single
2934 char* constant, indicating the name of the DLL represented
2935 by the import library.
2936
2937 It is possible to construct an import library that has
2938 two members with a non-empty .idata$7 section, but these
2939 are not often seen in normal operation. In this case,
2940 an error is flagged.
2941*/
2942static void
2943identify_dll_for_implib (void)
2944{
2945 bfd* abfd = NULL;
2946
2947 bfd_init ();
2948
2949 abfd = bfd_openr (identify_imp_name, 0);
2950 if (abfd == NULL)
2951 {
2952 bfd_fatal (identify_imp_name);
2953 }
2954 if (!bfd_check_format (abfd, bfd_archive))
2955 {
2956 if (!bfd_close (abfd))
2957 bfd_fatal (identify_imp_name);
2958
2959 fatal ("%s is not a library", identify_imp_name);
2960 }
2961
2962 identify_search_archive (abfd);
2963
2964 if (!bfd_close (abfd))
2965 bfd_fatal (identify_imp_name);
2966
2967 if (identify_dll_name && *identify_dll_name)
2968 {
2969 printf ("%s\n",identify_dll_name);
2970 free (identify_dll_name);
2971 identify_dll_name = NULL;
2972 }
2973 else
2974 {
2975 fatal ("Unable to determine dll name for %s (not an import library?)", identify_imp_name);
2976 }
2977}
2978
2979/* identify_search_archive
2980
2981 Loop over all members of the archive, inspecting
2982 each for the presence of an .idata$7 (.idata$6 on PPC)
2983 section with non-empty contents.
2984*/
2985static void
2986identify_search_archive (bfd* abfd)
2987{
2988 bfd *arfile = NULL;
2989 bfd *last_arfile = NULL;
2990 char **matching;
2991
2992 while (1)
2993 {
2994 arfile = bfd_openr_next_archived_file (abfd, arfile);
2995
2996 if (arfile == NULL)
2997 {
2998 if (bfd_get_error () != bfd_error_no_more_archived_files)
2999 bfd_fatal (bfd_get_filename (abfd));
3000 break;
3001 }
3002 if (bfd_check_format_matches (arfile, bfd_object, &matching))
3003 {
3004 identify_search_member (arfile, abfd);
3005 }
3006 else
3007 {
3008 bfd_nonfatal (bfd_get_filename (arfile));
3009 free (matching);
3010 }
3011 if (last_arfile != NULL)
3012 {
3013 bfd_close (last_arfile);
3014 }
3015 last_arfile = arfile;
3016 }
3017
3018 if (last_arfile != NULL)
3019 {
3020 bfd_close (last_arfile);
3021 }
3022}
3023
3024/* identify_search_member
3025
3026 Search all sections of an archive member for the
3027 one with section name of .idata$7 (.idata$6 on PPC)
3028 and non-empty contents.
3029*/
3030static void
3031identify_search_member (bfd* abfd, bfd* archive_bfd ATTRIBUTE_UNUSED)
3032{
3033 bfd_map_over_sections (abfd, identify_search_section, NULL);
3034}
3035
3036/* identify_process_section_p
3037
3038 This predicate returns true if section->name
3039 is .idata$7 (.idata$6 on PPC).
3040*/
3041static bfd_boolean
3042identify_process_section_p (asection * section)
3043{
3044 static const char * SECTION_NAME =
3045#ifdef DLLTOOL_PPC
3046 /* dllname is stored in idata$6 on PPC */
3047 ".idata$6";
3048#else
3049 ".idata$7";
3050#endif
3051
3052 if (strcmp (SECTION_NAME, section->name) == 0)
3053 return TRUE;
3054 return FALSE;
3055}
3056
3057/* identify_search_section
3058
3059 If *section has contents and its name is .idata$7
3060 (.data$6 on PPC) then store the contents in
3061 identify_dll_name as an xmalloc'ed array.
3062
3063 However, if identify_dll_name already has
3064 a value, flag an error. We don't know how to handle
3065 import libraries that directly reference more than
3066 one DLL. (This is different than forwarded symbols.
3067 Such import libraries are not seen in normal operation,
3068 and must be specifically constructed.)
3069*/
3070static void
3071identify_search_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
3072{
3073 bfd_byte *data = 0;
3074 bfd_size_type datasize;
3075
3076 if ((section->flags & SEC_HAS_CONTENTS) == 0)
3077 return;
3078
3079 if (! identify_process_section_p (section))
3080 return;
3081
3082 if ((datasize = bfd_section_size (abfd, section)) == 0)
3083 return;
3084
3085 data = (bfd_byte*) xmalloc (datasize + 1);
3086 data[0] = '\0';
3087
3088 bfd_get_section_contents (abfd, section, data, 0, datasize);
3089 data[datasize] = '\0';
3090
3091 if (data[0] != '\0')
3092 {
3093 if (identify_dll_name != NULL)
3094 {
3095 if (*identify_dll_name != '\0')
3096 {
3097 /* The import library specifies two different DLLs.
3098 Treat this as an error. */
3099 fatal ("Import library `%s' specifies two or more dlls: `%s' and `%s'",
3100 identify_imp_name, identify_dll_name, data);
3101 }
3102 else
3103 {
3104 /* For some reason memory was allocated, but the
3105 contents were empty. Free the memory and continue. */
3106 free (identify_dll_name);
3107 }
3108 }
9b91d2fc 3109 identify_dll_name = xstrdup ((char*) data);
d4732f7c
CW
3110 }
3111
3112 free (data);
3113}
3114
252b5132 3115/* Run through the information gathered from the .o files and the
c9e38879 3116 .def file and work out the best stuff. */
7aa52b1f 3117
252b5132 3118static int
2da42df6 3119pfunc (const void *a, const void *b)
252b5132
RH
3120{
3121 export_type *ap = *(export_type **) a;
3122 export_type *bp = *(export_type **) b;
3123 if (ap->ordinal == bp->ordinal)
3124 return 0;
3125
c9e38879 3126 /* Unset ordinals go to the bottom. */
252b5132
RH
3127 if (ap->ordinal == -1)
3128 return 1;
3129 if (bp->ordinal == -1)
3130 return -1;
3131 return (ap->ordinal - bp->ordinal);
3132}
3133
3134static int
2da42df6 3135nfunc (const void *a, const void *b)
252b5132
RH
3136{
3137 export_type *ap = *(export_type **) a;
3138 export_type *bp = *(export_type **) b;
c6972290
NC
3139 const char *an = ap->name;
3140 const char *bn = bp->name;
252b5132 3141
c6972290
NC
3142 if (killat)
3143 {
3144 an = (an[0] == '@') ? an + 1 : an;
3145 bn = (bn[0] == '@') ? bn + 1 : bn;
3146 }
3147
3148 return (strcmp (an, bn));
252b5132
RH
3149}
3150
3151static void
2da42df6 3152remove_null_names (export_type **ptr)
252b5132
RH
3153{
3154 int src;
3155 int dst;
c9e38879 3156
252b5132
RH
3157 for (dst = src = 0; src < d_nfuncs; src++)
3158 {
3159 if (ptr[src])
3160 {
3161 ptr[dst] = ptr[src];
3162 dst++;
3163 }
3164 }
3165 d_nfuncs = dst;
3166}
3167
252b5132 3168static void
2da42df6 3169process_duplicates (export_type **d_export_vec)
252b5132
RH
3170{
3171 int more = 1;
3172 int i;
c9e38879 3173
252b5132
RH
3174 while (more)
3175 {
252b5132 3176 more = 0;
c9e38879 3177 /* Remove duplicates. */
252b5132
RH
3178 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
3179
252b5132
RH
3180 for (i = 0; i < d_nfuncs - 1; i++)
3181 {
3182 if (strcmp (d_export_vec[i]->name,
3183 d_export_vec[i + 1]->name) == 0)
3184 {
252b5132
RH
3185 export_type *a = d_export_vec[i];
3186 export_type *b = d_export_vec[i + 1];
3187
3188 more = 1;
26044998 3189
252b5132 3190 /* xgettext:c-format */
37cc8ec1 3191 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"),
252b5132 3192 a->name, a->ordinal, b->ordinal);
26044998 3193
252b5132
RH
3194 if (a->ordinal != -1
3195 && b->ordinal != -1)
3196 /* xgettext:c-format */
ea6e992c 3197 fatal (_("Error, duplicate EXPORT with ordinals: %s"),
252b5132
RH
3198 a->name);
3199
c9e38879 3200 /* Merge attributes. */
252b5132
RH
3201 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
3202 b->constant |= a->constant;
3203 b->noname |= a->noname;
3204 b->data |= a->data;
3205 d_export_vec[i] = 0;
3206 }
3207
252b5132 3208 remove_null_names (d_export_vec);
252b5132
RH
3209 }
3210 }
3211
c9e38879 3212 /* Count the names. */
252b5132 3213 for (i = 0; i < d_nfuncs; i++)
7aa52b1f
NC
3214 if (!d_export_vec[i]->noname)
3215 d_named_nfuncs++;
252b5132
RH
3216}
3217
3218static void
2da42df6 3219fill_ordinals (export_type **d_export_vec)
252b5132
RH
3220{
3221 int lowest = -1;
3222 int i;
3223 char *ptr;
3224 int size = 65536;
3225
3226 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3227
c9e38879 3228 /* Fill in the unset ordinals with ones from our range. */
252b5132
RH
3229 ptr = (char *) xmalloc (size);
3230
3231 memset (ptr, 0, size);
3232
c9e38879 3233 /* Mark in our large vector all the numbers that are taken. */
252b5132
RH
3234 for (i = 0; i < d_nfuncs; i++)
3235 {
3236 if (d_export_vec[i]->ordinal != -1)
3237 {
3238 ptr[d_export_vec[i]->ordinal] = 1;
c9e38879 3239
252b5132 3240 if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
c9e38879 3241 lowest = d_export_vec[i]->ordinal;
252b5132
RH
3242 }
3243 }
3244
3245 /* Start at 1 for compatibility with MS toolchain. */
3246 if (lowest == -1)
3247 lowest = 1;
3248
26044998 3249 /* Now fill in ordinals where the user wants us to choose. */
252b5132
RH
3250 for (i = 0; i < d_nfuncs; i++)
3251 {
3252 if (d_export_vec[i]->ordinal == -1)
3253 {
7aa52b1f 3254 int j;
252b5132 3255
26044998 3256 /* First try within or after any user supplied range. */
252b5132
RH
3257 for (j = lowest; j < size; j++)
3258 if (ptr[j] == 0)
3259 {
3260 ptr[j] = 1;
3261 d_export_vec[i]->ordinal = j;
3262 goto done;
3263 }
3264
26044998 3265 /* Then try before the range. */
252b5132
RH
3266 for (j = lowest; j >0; j--)
3267 if (ptr[j] == 0)
3268 {
3269 ptr[j] = 1;
3270 d_export_vec[i]->ordinal = j;
3271 goto done;
3272 }
3273 done:;
3274 }
3275 }
3276
3277 free (ptr);
3278
c9e38879 3279 /* And resort. */
252b5132
RH
3280 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3281
3282 /* Work out the lowest and highest ordinal numbers. */
3283 if (d_nfuncs)
3284 {
3285 if (d_export_vec[0])
3286 d_low_ord = d_export_vec[0]->ordinal;
3287 if (d_export_vec[d_nfuncs-1])
3288 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
3289 }
3290}
3291
252b5132 3292static void
2da42df6 3293mangle_defs (void)
252b5132 3294{
c9e38879 3295 /* First work out the minimum ordinal chosen. */
252b5132
RH
3296 export_type *exp;
3297
3298 int i;
3299 int hint = 0;
7aa52b1f 3300 export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs);
252b5132
RH
3301
3302 inform (_("Processing definitions"));
26044998 3303
252b5132 3304 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
c9e38879 3305 d_export_vec[i] = exp;
252b5132
RH
3306
3307 process_duplicates (d_export_vec);
3308 fill_ordinals (d_export_vec);
3309
c9e38879 3310 /* Put back the list in the new order. */
252b5132
RH
3311 d_exports = 0;
3312 for (i = d_nfuncs - 1; i >= 0; i--)
3313 {
3314 d_export_vec[i]->next = d_exports;
3315 d_exports = d_export_vec[i];
3316 }
3317
c9e38879 3318 /* Build list in alpha order. */
252b5132
RH
3319 d_exports_lexically = (export_type **)
3320 xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
3321
3322 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
c9e38879
NC
3323 d_exports_lexically[i] = exp;
3324
252b5132
RH
3325 d_exports_lexically[i] = 0;
3326
c6972290 3327 qsort (d_exports_lexically, i, sizeof (export_type *), nfunc);
252b5132 3328
c9e38879 3329 /* Fill exp entries with their hint values. */
252b5132 3330 for (i = 0; i < d_nfuncs; i++)
c9e38879
NC
3331 if (!d_exports_lexically[i]->noname || show_allnames)
3332 d_exports_lexically[i]->hint = hint++;
26044998 3333
252b5132
RH
3334 inform (_("Processed definitions"));
3335}
3336
252b5132 3337static void
2da42df6 3338usage (FILE *file, int status)
252b5132
RH
3339{
3340 /* xgetext:c-format */
8b53311e 3341 fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
252b5132 3342 /* xgetext:c-format */
661016bb 3343 fprintf (file, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname);
7e301c9c 3344 fprintf (file, _(" possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb\n"));
252b5132
RH
3345 fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n"));
3346 fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
3347 fprintf (file, _(" -a --add-indirect Add dll indirects to export file.\n"));
3348 fprintf (file, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
3349 fprintf (file, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
3350 fprintf (file, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
661016bb
NC
3351 fprintf (file, _(" --export-all-symbols Export all symbols to .def\n"));
3352 fprintf (file, _(" --no-export-all-symbols Only export listed symbols\n"));
3353 fprintf (file, _(" --exclude-symbols <list> Don't export <list>\n"));
3354 fprintf (file, _(" --no-default-excludes Clear default exclude symbols\n"));
252b5132
RH
3355 fprintf (file, _(" -b --base-file <basefile> Read linker generated base file.\n"));
3356 fprintf (file, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
3357 fprintf (file, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
14288fdc
DS
3358 fprintf (file, _(" -U --add-underscore Add underscores to all symbols in interface library.\n"));
3359 fprintf (file, _(" --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n"));
252b5132
RH
3360 fprintf (file, _(" -k --kill-at Kill @<n> from exported names.\n"));
3361 fprintf (file, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
607dea97 3362 fprintf (file, _(" -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
252b5132
RH
3363 fprintf (file, _(" -S --as <name> Use <name> for assembler.\n"));
3364 fprintf (file, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
5f0f29c3 3365 fprintf (file, _(" -C --compat-implib Create backward compatible import library.\n"));
252b5132 3366 fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
f9346411 3367 fprintf (file, _(" -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
d4732f7c 3368 fprintf (file, _(" -I --identify <implib> Report the name of the DLL associated with <implib>.\n"));
252b5132
RH
3369 fprintf (file, _(" -v --verbose Be verbose.\n"));
3370 fprintf (file, _(" -V --version Display the program version.\n"));
3371 fprintf (file, _(" -h --help Display this information.\n"));
07012eee 3372 fprintf (file, _(" @<file> Read options from <file>.\n"));
49e315b1
NC
3373#ifdef DLLTOOL_MCORE_ELF
3374 fprintf (file, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n"));
3375 fprintf (file, _(" -L --linker <name> Use <name> as the linker.\n"));
3376 fprintf (file, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n"));
3377#endif
92f01d61
JM
3378 if (REPORT_BUGS_TO[0] && status == 0)
3379 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
3380 exit (status);
3381}
3382
3383#define OPTION_EXPORT_ALL_SYMS 150
3384#define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
3385#define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
3386#define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
14288fdc 3387#define OPTION_ADD_STDCALL_UNDERSCORE (OPTION_NO_DEFAULT_EXCLUDES + 1)
252b5132
RH
3388
3389static const struct option long_options[] =
3390{
3391 {"no-delete", no_argument, NULL, 'n'},
3392 {"dllname", required_argument, NULL, 'D'},
49e315b1
NC
3393 {"no-idata4", no_argument, NULL, 'x'},
3394 {"no-idata5", no_argument, NULL, 'c'},
252b5132
RH
3395 {"output-exp", required_argument, NULL, 'e'},
3396 {"output-def", required_argument, NULL, 'z'},
3397 {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
3398 {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
3399 {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
3400 {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
3401 {"output-lib", required_argument, NULL, 'l'},
50c2245b 3402 {"def", required_argument, NULL, 'd'}, /* for compatibility with older versions */
252b5132
RH
3403 {"input-def", required_argument, NULL, 'd'},
3404 {"add-underscore", no_argument, NULL, 'U'},
14288fdc 3405 {"add-stdcall-underscore", no_argument, NULL, OPTION_ADD_STDCALL_UNDERSCORE},
252b5132
RH
3406 {"kill-at", no_argument, NULL, 'k'},
3407 {"add-stdcall-alias", no_argument, NULL, 'A'},
607dea97 3408 {"ext-prefix-alias", required_argument, NULL, 'p'},
d4732f7c 3409 {"identify", required_argument, NULL, 'I'},
252b5132
RH
3410 {"verbose", no_argument, NULL, 'v'},
3411 {"version", no_argument, NULL, 'V'},
3412 {"help", no_argument, NULL, 'h'},
3413 {"machine", required_argument, NULL, 'm'},
3414 {"add-indirect", no_argument, NULL, 'a'},
3415 {"base-file", required_argument, NULL, 'b'},
3416 {"as", required_argument, NULL, 'S'},
3417 {"as-flags", required_argument, NULL, 'f'},
49e315b1 3418 {"mcore-elf", required_argument, NULL, 'M'},
5f0f29c3 3419 {"compat-implib", no_argument, NULL, 'C'},
0e11a9e9 3420 {"temp-prefix", required_argument, NULL, 't'},
5ea695ed 3421 {NULL,0,NULL,0}
252b5132
RH
3422};
3423
2da42df6 3424int main (int, char **);
e80ff7de 3425
252b5132 3426int
2da42df6 3427main (int ac, char **av)
252b5132
RH
3428{
3429 int c;
3430 int i;
3431 char *firstarg = 0;
3432 program_name = av[0];
3433 oav = av;
3434
3435#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3436 setlocale (LC_MESSAGES, "");
3882b010
L
3437#endif
3438#if defined (HAVE_SETLOCALE)
3439 setlocale (LC_CTYPE, "");
252b5132
RH
3440#endif
3441 bindtextdomain (PACKAGE, LOCALEDIR);
3442 textdomain (PACKAGE);
3443
c843b1bb 3444 expandargv (&ac, &av);
869b9d07 3445
49e315b1 3446 while ((c = getopt_long (ac, av,
26044998 3447#ifdef DLLTOOL_MCORE_ELF
d4732f7c 3448 "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHhM:L:F:",
49e315b1 3449#else
d4732f7c 3450 "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh",
49e315b1 3451#endif
252b5132
RH
3452 long_options, 0))
3453 != EOF)
3454 {
3455 switch (c)
3456 {
252b5132 3457 case OPTION_EXPORT_ALL_SYMS:
b34976b6 3458 export_all_symbols = TRUE;
252b5132
RH
3459 break;
3460 case OPTION_NO_EXPORT_ALL_SYMS:
b34976b6 3461 export_all_symbols = FALSE;
252b5132
RH
3462 break;
3463 case OPTION_EXCLUDE_SYMS:
3464 add_excludes (optarg);
3465 break;
3466 case OPTION_NO_DEFAULT_EXCLUDES:
b34976b6 3467 do_default_excludes = FALSE;
252b5132 3468 break;
14288fdc
DS
3469 case OPTION_ADD_STDCALL_UNDERSCORE:
3470 add_stdcall_underscore = 1;
3471 break;
49e315b1
NC
3472 case 'x':
3473 no_idata4 = 1;
3474 break;
3475 case 'c':
3476 no_idata5 = 1;
3477 break;
252b5132
RH
3478 case 'S':
3479 as_name = optarg;
3480 break;
0e11a9e9
CF
3481 case 't':
3482 tmp_prefix = optarg;
3483 break;
252b5132
RH
3484 case 'f':
3485 as_flags = optarg;
3486 break;
3487
7aa52b1f 3488 /* Ignored for compatibility. */
252b5132
RH
3489 case 'u':
3490 break;
3491 case 'a':
3492 add_indirect = 1;
3493 break;
3494 case 'z':
3495 output_def = fopen (optarg, FOPEN_WT);
3496 break;
3497 case 'D':
a0ce7f12
DS
3498 dll_name = (char*) lbasename (optarg);
3499 if (dll_name != optarg)
3500 non_fatal (_("Path components stripped from dllname, '%s'."),
3501 optarg);
252b5132
RH
3502 break;
3503 case 'l':
3504 imp_name = optarg;
3505 break;
3506 case 'e':
3507 exp_name = optarg;
3508 break;
8b53311e 3509 case 'H':
252b5132
RH
3510 case 'h':
3511 usage (stdout, 0);
3512 break;
3513 case 'm':
3514 mname = optarg;
3515 break;
d4732f7c
CW
3516 case 'I':
3517 identify_imp_name = optarg;
3518 break;
252b5132
RH
3519 case 'v':
3520 verbose = 1;
3521 break;
3522 case 'V':
3523 print_version (program_name);
3524 break;
252b5132
RH
3525 case 'U':
3526 add_underscore = 1;
3527 break;
3528 case 'k':
3529 killat = 1;
3530 break;
3531 case 'A':
3532 add_stdcall_alias = 1;
3533 break;
607dea97
NC
3534 case 'p':
3535 ext_prefix_alias = optarg;
3536 break;
252b5132
RH
3537 case 'd':
3538 def_file = optarg;
3539 break;
3540 case 'n':
3541 dontdeltemps++;
3542 break;
3543 case 'b':
3544 base_file = fopen (optarg, FOPEN_RB);
26044998 3545
252b5132
RH
3546 if (!base_file)
3547 /* xgettext:c-format */
3548 fatal (_("Unable to open base-file: %s"), optarg);
3549
3550 break;
49e315b1
NC
3551#ifdef DLLTOOL_MCORE_ELF
3552 case 'M':
3553 mcore_elf_out_file = optarg;
3554 break;
3555 case 'L':
3556 mcore_elf_linker = optarg;
3557 break;
3558 case 'F':
3559 mcore_elf_linker_flags = optarg;
3560 break;
3561#endif
5f0f29c3
NC
3562 case 'C':
3563 create_compat_implib = 1;
3564 break;
252b5132
RH
3565 default:
3566 usage (stderr, 1);
3567 break;
3568 }
3569 }
3570
bf7a6389
CF
3571 if (!tmp_prefix)
3572 tmp_prefix = prefix_encode ("d", getpid ());
3573
252b5132 3574 for (i = 0; mtable[i].type; i++)
762100ed
NC
3575 if (strcmp (mtable[i].type, mname) == 0)
3576 break;
252b5132
RH
3577
3578 if (!mtable[i].type)
3579 /* xgettext:c-format */
3580 fatal (_("Machine '%s' not supported"), mname);
3581
3582 machine = i;
3583
252b5132
RH
3584 if (!dll_name && exp_name)
3585 {
a0ce7f12
DS
3586 /* If we are inferring dll_name from exp_name,
3587 strip off any path components, without emitting
3588 a warning. */
3589 const char* exp_basename = lbasename (exp_name);
3590 const int len = strlen (exp_basename) + 5;
252b5132 3591 dll_name = xmalloc (len);
a0ce7f12 3592 strcpy (dll_name, exp_basename);
252b5132
RH
3593 strcat (dll_name, ".dll");
3594 }
3595
49e315b1
NC
3596 if (as_name == NULL)
3597 as_name = deduce_name ("as");
26044998 3598
252b5132
RH
3599 /* Don't use the default exclude list if we're reading only the
3600 symbols in the .drectve section. The default excludes are meant
3601 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3602 if (! export_all_symbols)
b34976b6 3603 do_default_excludes = FALSE;
26044998 3604
252b5132
RH
3605 if (do_default_excludes)
3606 set_default_excludes ();
3607
3608 if (def_file)
3609 process_def_file (def_file);
3610
3611 while (optind < ac)
3612 {
3613 if (!firstarg)
3614 firstarg = av[optind];
3615 scan_obj_file (av[optind]);
3616 optind++;
3617 }
3618
3619 mangle_defs ();
3620
3621 if (exp_name)
3622 gen_exp_file ();
26044998 3623
252b5132
RH
3624 if (imp_name)
3625 {
26044998 3626 /* Make imp_name safe for use as a label. */
252b5132
RH
3627 char *p;
3628
3629 imp_name_lab = xstrdup (imp_name);
3630 for (p = imp_name_lab; *p; p++)
3631 {
3882b010 3632 if (!ISALNUM (*p))
252b5132
RH
3633 *p = '_';
3634 }
3635 head_label = make_label("_head_", imp_name_lab);
3636 gen_lib_file ();
3637 }
26044998 3638
252b5132
RH
3639 if (output_def)
3640 gen_def_file ();
26044998 3641
d4732f7c
CW
3642 if (identify_imp_name)
3643 {
3644 identify_dll_for_implib ();
3645 }
3646
49e315b1
NC
3647#ifdef DLLTOOL_MCORE_ELF
3648 if (mcore_elf_out_file)
3649 mcore_elf_gen_out_file ();
3650#endif
26044998 3651
252b5132
RH
3652 return 0;
3653}
49e315b1 3654
bb0cb4db
ILT
3655/* Look for the program formed by concatenating PROG_NAME and the
3656 string running from PREFIX to END_PREFIX. If the concatenated
3657 string contains a '/', try appending EXECUTABLE_SUFFIX if it is
2481e6a2 3658 appropriate. */
bb0cb4db
ILT
3659
3660static char *
2da42df6 3661look_for_prog (const char *prog_name, const char *prefix, int end_prefix)
bb0cb4db
ILT
3662{
3663 struct stat s;
3664 char *cmd;
3665
26044998
KH
3666 cmd = xmalloc (strlen (prefix)
3667 + strlen (prog_name)
2481e6a2 3668#ifdef HAVE_EXECUTABLE_SUFFIX
26044998 3669 + strlen (EXECUTABLE_SUFFIX)
bb0cb4db
ILT
3670#endif
3671 + 10);
3672 strcpy (cmd, prefix);
3673
3674 sprintf (cmd + end_prefix, "%s", prog_name);
3675
3676 if (strchr (cmd, '/') != NULL)
3677 {
3678 int found;
3679
3680 found = (stat (cmd, &s) == 0
2481e6a2 3681#ifdef HAVE_EXECUTABLE_SUFFIX
26044998 3682 || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0
bb0cb4db
ILT
3683#endif
3684 );
3685
3686 if (! found)
26044998 3687 {
bb0cb4db
ILT
3688 /* xgettext:c-format */
3689 inform (_("Tried file: %s"), cmd);
3690 free (cmd);
3691 return NULL;
3692 }
3693 }
3694
3695 /* xgettext:c-format */
3696 inform (_("Using file: %s"), cmd);
3697
3698 return cmd;
3699}
3700
49e315b1
NC
3701/* Deduce the name of the program we are want to invoke.
3702 PROG_NAME is the basic name of the program we want to run,
3703 eg "as" or "ld". The catch is that we might want actually
26044998 3704 run "i386-pe-as" or "ppc-pe-ld".
bb0cb4db
ILT
3705
3706 If argv[0] contains the full path, then try to find the program
3707 in the same place, with and then without a target-like prefix.
3708
3709 Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
26044998 3710 deduce_name("as") uses the following search order:
bb0cb4db
ILT
3711
3712 /usr/local/bin/i586-cygwin32-as
3713 /usr/local/bin/as
3714 as
26044998 3715
bb0cb4db
ILT
3716 If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
3717 name, it'll try without and then with EXECUTABLE_SUFFIX.
3718
3719 Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
3720 as the fallback, but rather return i586-cygwin32-as.
26044998 3721
bb0cb4db
ILT
3722 Oh, and given, argv[0] = dlltool, it'll return "as".
3723
3724 Returns a dynamically allocated string. */
3725
49e315b1 3726static char *
2da42df6 3727deduce_name (const char *prog_name)
49e315b1 3728{
bb0cb4db
ILT
3729 char *cmd;
3730 char *dash, *slash, *cp;
49e315b1 3731
bb0cb4db
ILT
3732 dash = NULL;
3733 slash = NULL;
3734 for (cp = program_name; *cp != '\0'; ++cp)
3735 {
3736 if (*cp == '-')
3737 dash = cp;
3738 if (
3739#if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
3740 *cp == ':' || *cp == '\\' ||
3741#endif
3742 *cp == '/')
3743 {
3744 slash = cp;
3745 dash = NULL;
3746 }
3747 }
49e315b1 3748
bb0cb4db 3749 cmd = NULL;
49e315b1 3750
bb0cb4db
ILT
3751 if (dash != NULL)
3752 {
3753 /* First, try looking for a prefixed PROG_NAME in the
3754 PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */
3755 cmd = look_for_prog (prog_name, program_name, dash - program_name + 1);
3756 }
49e315b1 3757
bb0cb4db
ILT
3758 if (slash != NULL && cmd == NULL)
3759 {
3760 /* Next, try looking for a PROG_NAME in the same directory as
3761 that of this program. */
3762 cmd = look_for_prog (prog_name, program_name, slash - program_name + 1);
3763 }
3764
3765 if (cmd == NULL)
3766 {
3767 /* Just return PROG_NAME as is. */
3768 cmd = xstrdup (prog_name);
3769 }
3770
3771 return cmd;
49e315b1
NC
3772}
3773
3774#ifdef DLLTOOL_MCORE_ELF
3775typedef struct fname_cache
3776{
fd64a958 3777 const char * filename;
49e315b1
NC
3778 struct fname_cache * next;
3779}
3780fname_cache;
3781
3782static fname_cache fnames;
3783
3784static void
fd64a958 3785mcore_elf_cache_filename (const char * filename)
49e315b1
NC
3786{
3787 fname_cache * ptr;
3788
3789 ptr = & fnames;
3790
3791 while (ptr->next != NULL)
3792 ptr = ptr->next;
3793
3794 ptr->filename = filename;
3795 ptr->next = (fname_cache *) malloc (sizeof (fname_cache));
3796 if (ptr->next != NULL)
3797 ptr->next->next = NULL;
3798}
3799
762100ed
NC
3800#define MCORE_ELF_TMP_OBJ "mcoreelf.o"
3801#define MCORE_ELF_TMP_EXP "mcoreelf.exp"
3802#define MCORE_ELF_TMP_LIB "mcoreelf.lib"
3803
49e315b1
NC
3804static void
3805mcore_elf_gen_out_file (void)
3806{
3807 fname_cache * ptr;
bb0cb4db 3808 dyn_string_t ds;
49e315b1
NC
3809
3810 /* Step one. Run 'ld -r' on the input object files in order to resolve
3811 any internal references and to generate a single .exports section. */
3812 ptr = & fnames;
3813
bb0cb4db 3814 ds = dyn_string_new (100);
55b9cdf1 3815 dyn_string_append_cstr (ds, "-r ");
49e315b1
NC
3816
3817 if (mcore_elf_linker_flags != NULL)
55b9cdf1 3818 dyn_string_append_cstr (ds, mcore_elf_linker_flags);
26044998 3819
49e315b1
NC
3820 while (ptr->next != NULL)
3821 {
55b9cdf1
AM
3822 dyn_string_append_cstr (ds, ptr->filename);
3823 dyn_string_append_cstr (ds, " ");
49e315b1
NC
3824
3825 ptr = ptr->next;
3826 }
3827
55b9cdf1
AM
3828 dyn_string_append_cstr (ds, "-o ");
3829 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
49e315b1
NC
3830
3831 if (mcore_elf_linker == NULL)
3832 mcore_elf_linker = deduce_name ("ld");
26044998 3833
bb0cb4db
ILT
3834 run (mcore_elf_linker, ds->s);
3835
3836 dyn_string_delete (ds);
49e315b1 3837
26044998 3838 /* Step two. Create a .exp file and a .lib file from the temporary file.
c9e38879 3839 Do this by recursively invoking dlltool... */
bb0cb4db
ILT
3840 ds = dyn_string_new (100);
3841
55b9cdf1
AM
3842 dyn_string_append_cstr (ds, "-S ");
3843 dyn_string_append_cstr (ds, as_name);
26044998 3844
55b9cdf1
AM
3845 dyn_string_append_cstr (ds, " -e ");
3846 dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP);
3847 dyn_string_append_cstr (ds, " -l ");
3848 dyn_string_append_cstr (ds, MCORE_ELF_TMP_LIB);
3849 dyn_string_append_cstr (ds, " " );
3850 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
49e315b1
NC
3851
3852 if (verbose)
55b9cdf1 3853 dyn_string_append_cstr (ds, " -v");
26044998 3854
49e315b1 3855 if (dontdeltemps)
762100ed 3856 {
55b9cdf1 3857 dyn_string_append_cstr (ds, " -n");
26044998 3858
762100ed 3859 if (dontdeltemps > 1)
55b9cdf1 3860 dyn_string_append_cstr (ds, " -n");
762100ed 3861 }
49e315b1
NC
3862
3863 /* XXX - FIME: ought to check/copy other command line options as well. */
bb0cb4db
ILT
3864 run (program_name, ds->s);
3865
3866 dyn_string_delete (ds);
49e315b1 3867
74479bd3 3868 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */
bb0cb4db
ILT
3869 ds = dyn_string_new (100);
3870
55b9cdf1 3871 dyn_string_append_cstr (ds, "-shared ");
49e315b1
NC
3872
3873 if (mcore_elf_linker_flags)
55b9cdf1
AM
3874 dyn_string_append_cstr (ds, mcore_elf_linker_flags);
3875
3876 dyn_string_append_cstr (ds, " ");
3877 dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP);
3878 dyn_string_append_cstr (ds, " ");
3879 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
3880 dyn_string_append_cstr (ds, " -o ");
3881 dyn_string_append_cstr (ds, mcore_elf_out_file);
49e315b1 3882
bb0cb4db 3883 run (mcore_elf_linker, ds->s);
49e315b1 3884
bb0cb4db 3885 dyn_string_delete (ds);
762100ed
NC
3886
3887 if (dontdeltemps == 0)
74479bd3 3888 unlink (MCORE_ELF_TMP_EXP);
762100ed
NC
3889
3890 if (dontdeltemps < 2)
3891 unlink (MCORE_ELF_TMP_OBJ);
49e315b1
NC
3892}
3893#endif /* DLLTOOL_MCORE_ELF */
This page took 0.60524 seconds and 4 git commands to generate.