Apply patches from PRs 16299, 17008 and 17140
[deliverable/binutils-gdb.git] / binutils / dlltool.c
CommitLineData
c027e8b0 1/* dlltool.c -- tool to generate stuff for PE style DLLs
c336631b 2 Copyright (C) 1995, 96, 97, 1998 Free Software Foundation, Inc.
765e60a9
SC
3
4 This file is part of GNU Binutils.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
9d04d618
TT
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
765e60a9
SC
20
21
22/*
23 This program allows you to build the files necessary to create
24 DLLs to run on a system which understands PE format image files.
25 (eg, Windows NT)
26
a33f7359
ILT
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
765e60a9
SC
32 A DLL contains an export table which contains the information
33 which the runtime loader needs to tie up references from a
c027e8b0 34 referencing program.
765e60a9
SC
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
199f5217 38 DLL. A .o file can contain information in special ".drectve" sections
c027e8b0 39 with export information.
765e60a9
SC
40
41 A DEF file contains any number of the following commands:
42
43
c027e8b0 44 NAME <name> [ , <base> ]
6f2d3212 45 The result is going to be <name>.EXE
765e60a9 46
c027e8b0 47 LIBRARY <name> [ , <base> ]
6f2d3212 48 The result is going to be <name>.DLL
765e60a9 49
c336631b 50 EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] ) *
6f2d3212
SC
51 Declares name1 as an exported symbol from the
52 DLL, with optional ordinal number <integer>
765e60a9 53
061ed861
NC
54 IMPORTS ( ( <internal-name> = <module-name> . <integer> )
55 | ( [ <internal-name> = ] <module-name> . <external-name> )) *
56 Declares that <external-name> or the exported function whoes ordinal number
57 is <integer> is to be imported from the file <module-name>. If
58 <internal-name> is specified then this is the name that the imported
59 function will be refered to in the body of the DLL.
765e60a9
SC
60
61 DESCRIPTION <string>
6f2d3212 62 Puts <string> into output .exp file in the .rdata section
765e60a9
SC
63
64 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
6f2d3212 65 Generates --stack|--heap <number-reserve>,<number-commit>
199f5217 66 in the output .drectve section. The linker will
6f2d3212 67 see this and act upon it.
765e60a9
SC
68
69 [CODE|DATA] <attr>+
70 SECTIONS ( <sectionname> <attr>+ )*
6f2d3212
SC
71 <attr> = READ | WRITE | EXECUTE | SHARED
72 Generates --attr <sectionname> <attr> in the output
199f5217 73 .drectve section. The linker will see this and act
6f2d3212 74 upon it.
765e60a9
SC
75
76
199f5217 77 A -export:<name> in a .drectve section in an input .o or .a
765e60a9
SC
78 file to this program is equivalent to a EXPORTS <name>
79 in a .DEF file.
80
81
82
6f2d3212 83 The program generates output files with the prefix supplied
c027e8b0 84 on the command line, or in the def file, or taken from the first
6f2d3212 85 supplied argument.
765e60a9 86
6f2d3212
SC
87 The .exp.s file contains the information necessary to export
88 the routines in the DLL. The .lib.s file contains the information
89 necessary to use the DLL's routines from a referencing program.
765e60a9
SC
90
91
92
6f2d3212 93 Example:
765e60a9 94
061ed861 95 file1.c:
c027e8b0 96 asm (".section .drectve");
6f2d3212 97 asm (".ascii \"-export:adef\"");
765e60a9 98
061ed861 99 void adef (char * s)
6f2d3212 100 {
061ed861 101 printf ("hello from the dll %s\n", s);
6f2d3212 102 }
765e60a9 103
061ed861 104 void bdef (char * s)
6f2d3212 105 {
061ed861 106 printf ("hello from the dll and the other entry point %s\n", s);
6f2d3212 107 }
765e60a9 108
061ed861 109 file2.c:
6f2d3212
SC
110 asm (".section .drectve");
111 asm (".ascii \"-export:cdef\"");
112 asm (".ascii \"-export:ddef\"");
061ed861
NC
113
114 void cdef (char * s)
6f2d3212 115 {
061ed861 116 printf ("hello from the dll %s\n", s);
6f2d3212 117 }
765e60a9 118
061ed861 119 void ddef (char * s)
6f2d3212 120 {
061ed861 121 printf ("hello from the dll and the other entry point %s\n", s);
6f2d3212 122 }
765e60a9 123
6f2d3212
SC
124 printf()
125 {
061ed861 126 return 9;
6f2d3212 127 }
765e60a9 128
061ed861 129 main.c
765e60a9 130
061ed861 131 void main()
6f2d3212 132 {
061ed861 133 cdef();
6f2d3212 134 }
765e60a9 135
061ed861 136 thedll.def
765e60a9 137
6f2d3212
SC
138 LIBRARY thedll
139 HEAPSIZE 0x40000, 0x2000
140 EXPORTS bdef @ 20
061ed861 141 cdef @ 30 NONAME
765e60a9 142
6f2d3212
SC
143 SECTIONS donkey READ WRITE
144 aardvark EXECUTE
765e60a9 145
061ed861 146 # compile up the parts of the dll
765e60a9 147
c027e8b0 148 gcc -c file1.c
6f2d3212 149 gcc -c file2.c
765e60a9 150
061ed861
NC
151 # put them in a library (you don't have to, you
152 # could name all the .os on the dlltool line)
765e60a9 153
6f2d3212
SC
154 ar qcv thedll.in file1.o file2.o
155 ranlib thedll.in
765e60a9 156
061ed861 157 # run this tool over the library and the def file
2757dc25 158 ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
765e60a9 159
061ed861 160 # build the dll with the library with file1.o, file2.o and the export table
2757dc25 161 ld -o thedll.dll thedll.o thedll.in
765e60a9 162
061ed861 163 # build the mainline
c027e8b0 164 gcc -c themain.c
765e60a9 165
061ed861 166 # link the executable with the import library
2757dc25 167 ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
765e60a9 168
6f2d3212 169 */
765e60a9 170
e503032e
DE
171/* .idata section description
172
173 The .idata section is the import table. It is a collection of several
174 subsections used to keep the pieces for each dll together: .idata$[234567].
175 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
176
177 .idata$2 = Import Directory Table
178 = array of IMAGE_IMPORT_DESCRIPTOR's.
e503032e 179
061ed861 180 DWORD Import Lookup Table; - pointer to .idata$4
e503032e
DE
181 DWORD TimeDateStamp; - currently always 0
182 DWORD ForwarderChain; - currently always 0
183 DWORD Name; - pointer to dll's name
184 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
185
eedc864a 186 .idata$3 = null terminating entry for .idata$2.
e503032e
DE
187
188 .idata$4 = Import Lookup Table
189 = array of array of pointers to hint name table.
190 There is one for each dll being imported from, and each dll's set is
191 terminated by a trailing NULL.
192
193 .idata$5 = Import Address Table
194 = array of array of pointers to hint name table.
195 There is one for each dll being imported from, and each dll's set is
196 terminated by a trailing NULL.
197 Initially, this table is identical to the Import Lookup Table. However,
198 at load time, the loader overwrites the entries with the address of the
199 function.
200
201 .idata$6 = Hint Name Table
202 = Array of { short, asciz } entries, one for each imported function.
203 The `short' is the function's ordinal number.
204
205 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)
206*/
207
a33f7359
ILT
208/* AIX requires this to be the first thing in the file. */
209#ifndef __GNUC__
210# ifdef _AIX
211 #pragma alloca
212#endif
213#endif
214
215#define show_allnames 0
216
6f2d3212
SC
217#define PAGE_SIZE 4096
218#define PAGE_MASK (-PAGE_SIZE)
765e60a9 219#include "bfd.h"
27fca56f
ILT
220#include "libiberty.h"
221#include "bucomm.h"
222#include "getopt.h"
531f86b4 223#include "demangle.h"
a33f7359
ILT
224#include "dlltool.h"
225
356c68ff 226#include <ctype.h>
a33f7359 227#include <time.h>
061ed861
NC
228#ifdef __STDC__
229#include <stdarg.h>
230#else
231#include <varargs.h>
232#endif
233
234#ifdef DLLTOOL_ARM
235#include "coff/arm.h"
236#include "coff/internal.h"
237#endif
a33f7359 238
27fca56f
ILT
239#ifdef HAVE_SYS_WAIT_H
240#include <sys/wait.h>
9d04d618
TT
241#else /* ! HAVE_SYS_WAIT_H */
242#if ! defined (_WIN32) || defined (__CYGWIN32__)
27fca56f
ILT
243#ifndef WIFEXITED
244#define WIFEXITED(w) (((w)&0377) == 0)
245#endif
246#ifndef WIFSIGNALED
247#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
248#endif
249#ifndef WTERMSIG
250#define WTERMSIG(w) ((w) & 0177)
251#endif
252#ifndef WEXITSTATUS
253#define WEXITSTATUS(w) (((w) >> 8) & 0377)
254#endif
9d04d618
TT
255#else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
256#ifndef WIFEXITED
257#define WIFEXITED(w) (((w) & 0xff) == 0)
27fca56f 258#endif
9d04d618
TT
259#ifndef WIFSIGNALED
260#define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
261#endif
262#ifndef WTERMSIG
263#define WTERMSIG(w) ((w) & 0x7f)
264#endif
265#ifndef WEXITSTATUS
266#define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
267#endif
268#endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
269#endif /* ! HAVE_SYS_WAIT_H */
2757dc25 270
c027e8b0 271/* ifunc and ihead data structures: ttk@cygnus.com 1997
a4e5fd18 272
c027e8b0
ILT
273 When IMPORT declarations are encountered in a .def file the
274 function import information is stored in a structure referenced by
275 the global variable IMPORT_LIST. The structure is a linked list
276 containing the names of the dll files each function is imported
277 from and a linked list of functions being imported from that dll
278 file. This roughly parallels the structure of the .idata section
279 in the PE object file.
280
281 The contents of .def file are interpreted from within the
282 process_def_file function. Every time an IMPORT declaration is
283 encountered, it is broken up into its component parts and passed to
284 def_import. IMPORT_LIST is initialized to NULL in function main. */
285
286typedef struct ifunct
287{
288 char *name; /* name of function being imported */
289 int ord; /* two-byte ordinal value associated with function */
290 struct ifunct *next;
291} ifunctype;
292
293typedef struct iheadt
294{
295 char *dllname; /* name of dll file imported from */
296 long nfuncs; /* number of functions in list */
297 struct ifunct *funchead; /* first function in list */
298 struct ifunct *functail; /* last function in list */
299 struct iheadt *next; /* next dll file in list */
300} iheadtype;
301
302/* Structure containing all import information as defined in .def file
303 (qv "ihead structure"). */
a4e5fd18 304
c027e8b0 305static iheadtype *import_list = NULL;
a4e5fd18 306
a33f7359 307static char *as_name = "as";
061ed861 308static char * as_flags = "";
fb257042 309
356c68ff
SC
310static int no_idata4;
311static int no_idata5;
312static char *exp_name;
313static char *imp_name;
314static char *head_label;
315static char *imp_name_lab;
316static char *dll_name;
2757dc25 317
356c68ff
SC
318static int add_indirect = 0;
319static int add_underscore = 0;
320static int dontdeltemps = 0;
fb257042 321
061ed861
NC
322#ifdef DLLTOOL_ARM
323static int interwork = 0;
324#endif
325
faad4b47
ILT
326/* True if we should export all symbols. Otherwise, we only export
327 symbols listed in .drectve sections or in the def file. */
328static boolean export_all_symbols;
329
330/* True if we should exclude the symbols in DEFAULT_EXCLUDES when
331 exporting all symbols. */
332static boolean do_default_excludes;
333
334/* Default symbols to exclude when exporting all the symbols. */
335static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";
336
356c68ff 337static char *def_file;
2757dc25 338
061ed861 339extern char * program_name;
765e60a9
SC
340
341static int machine;
a33f7359 342static int killat;
6f2d3212 343static int verbose;
a33f7359
ILT
344static FILE *output_def;
345static FILE *base_file;
6d93c360 346
765e60a9 347#ifdef DLLTOOL_ARM
a33f7359 348static const char *mname = "arm";
765e60a9
SC
349#endif
350
351#ifdef DLLTOOL_I386
a33f7359 352static const char *mname = "i386";
765e60a9 353#endif
6d93c360
ILT
354
355#ifdef DLLTOOL_PPC
a33f7359 356static const char *mname = "ppc";
6d93c360
ILT
357#endif
358
6f2d3212 359#define PATHMAX 250 /* What's the right name for this ? */
765e60a9 360
061ed861
NC
361#define TMP_ASM "dc.s"
362#define TMP_HEAD_S "dh.s"
363#define TMP_HEAD_O "dh.o"
364#define TMP_TAIL_S "dt.s"
365#define TMP_TAIL_O "dt.o"
366#define TMP_STUB "ds"
367
356c68ff
SC
368/* This bit of assemly does jmp * ....
369s set how_jtab_roff to mark where the 32bit abs branch should go */
a33f7359
ILT
370static const unsigned char i386_jtab[] =
371{
372 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
373};
356c68ff 374
a33f7359
ILT
375static const unsigned char arm_jtab[] =
376{
377 0x00, 0xc0, 0x9f, 0xe5,
378 0x00, 0xf0, 0x9c, 0xe5,
379 0, 0, 0, 0
380};
6d93c360 381
061ed861
NC
382static const unsigned char thumb_jtab[] =
383{
384 0xc0, 0xb4,
385 0x02, 0x4e,
386 0x36, 0x68,
387 0x01, 0x96,
388 0x40, 0xbd,
389 0xc0, 0x46,
390 0, 0, 0, 0
391};
392
b10f8e5e
KK
393/* This is the glue sequence for PowerPC PE. There is a */
394/* tocrel16-tocdefn reloc against the first instruction. */
395/* We also need a IMGLUE reloc against the glue function */
396/* to restore the toc saved by the third instruction in */
397/* the glue. */
c027e8b0
ILT
398static const unsigned char ppc_jtab[] =
399{
b10f8e5e
KK
400 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
401 /* Reloc TOCREL16 __imp_xxx */
402 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
403 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
404 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
405 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
406 0x20, 0x04, 0x80, 0x4E /* bctr */
407};
408
a33f7359 409#ifdef DLLTOOL_PPC
b10f8e5e
KK
410/* the glue instruction, picks up the toc from the stw in */
411/* the above code: "lwz r2,4(r1)" */
a33f7359
ILT
412static bfd_vma ppc_glue_insn = 0x80410004;
413#endif
b10f8e5e 414
061ed861
NC
415/* The outfile array must be big enough to contain a fully
416 qualified path name, plus an arbitary series of command
417 line switches. We hope that PATH_MAX times two will be
418 enough. */
419static char outfile [PATHMAX * 2];
6d93c360 420
765e60a9 421struct mac
6f2d3212 422 {
a33f7359
ILT
423 const char *type;
424 const char *how_byte;
425 const char *how_short;
426 const char *how_long;
427 const char *how_asciz;
428 const char *how_comment;
429 const char *how_jump;
430 const char *how_global;
431 const char *how_space;
432 const char *how_align_short;
433 const char *how_align_long;
434 const char *how_bfd_target;
356c68ff 435 enum bfd_architecture how_bfd_arch;
a33f7359 436 const unsigned char *how_jtab;
356c68ff
SC
437 int how_jtab_size; /* size of the jtab entry */
438 int how_jtab_roff; /* offset into it for the ind 32 reloc into idata 5 */
a33f7359
ILT
439 };
440
061ed861
NC
441static const struct mac
442mtable[] =
765e60a9 443{
6f2d3212 444 {
f88ebc68 445#define MARM 0
c027e8b0 446 "arm", ".byte", ".short", ".long", ".asciz", "@",
356c68ff
SC
447 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
448 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
061ed861 449 arm_jtab, sizeof (arm_jtab), 8
6f2d3212
SC
450 }
451 ,
452 {
f88ebc68 453#define M386 1
356c68ff 454 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386,
061ed861 455 i386_jtab, sizeof (i386_jtab), 2
6f2d3212
SC
456 }
457 ,
6d93c360
ILT
458 {
459#define MPPC 2
460 "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc,
061ed861
NC
461 ppc_jtab, sizeof (ppc_jtab), 0
462 }
463 ,
464 {
465#define MTHUMB 3
466 "thumb", ".byte", ".short", ".long", ".asciz", "@",
467 "push\t{r6, r7}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tstr\tr6, [sp, #4]\n\tpop\t{r6, pc}\n\tnop",
468 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
469 thumb_jtab, sizeof (thumb_jtab), 12
6d93c360
ILT
470 }
471 ,
356c68ff 472{ 0}
6f2d3212 473};
765e60a9 474
a33f7359
ILT
475typedef struct dlist
476{
477 char *text;
478 struct dlist *next;
479}
480dlist_type;
2757dc25 481
a33f7359
ILT
482typedef struct export
483 {
484 const char *name;
485 const char *internal_name;
486 int ordinal;
487 int constant;
488 int noname;
c336631b 489 int data;
a33f7359
ILT
490 int hint;
491 struct export *next;
492 }
493export_type;
494
faad4b47
ILT
495/* A list of symbols which we should not export. */
496
497struct string_list
498{
499 struct string_list *next;
500 char *string;
501};
502
503static struct string_list *excludes;
504
a33f7359
ILT
505static const char *rvaafter PARAMS ((int));
506static const char *rvabefore PARAMS ((int));
507static const char *asm_prefix PARAMS ((int));
c027e8b0 508static void append_import PARAMS ((const char *, const char *, int));
a33f7359 509static void run PARAMS ((const char *, char *));
faad4b47
ILT
510static void scan_drectve_symbols PARAMS ((bfd *));
511static void scan_filtered_symbols PARAMS ((bfd *, PTR, long, unsigned int));
512static void add_excludes PARAMS ((const char *));
513static boolean match_exclude PARAMS ((const char *));
514static void set_default_excludes PARAMS ((void));
515static long filter_symbols PARAMS ((bfd *, PTR, long, unsigned int));
516static void scan_all_symbols PARAMS ((bfd *));
a33f7359
ILT
517static void scan_open_obj_file PARAMS ((bfd *));
518static void scan_obj_file PARAMS ((const char *));
519static void dump_def_info PARAMS ((FILE *));
520static int sfunc PARAMS ((const void *, const void *));
521static void flush_page PARAMS ((FILE *, long *, int, int));
522static void gen_def_file PARAMS ((void));
c027e8b0 523static void generate_idata_ofile PARAMS ((FILE *));
a33f7359
ILT
524static void gen_exp_file PARAMS ((void));
525static const char *xlate PARAMS ((const char *));
faad4b47 526#if 0
a33f7359 527static void dump_iat PARAMS ((FILE *, export_type *));
faad4b47 528#endif
a33f7359
ILT
529static char *make_label PARAMS ((const char *, const char *));
530static bfd *make_one_lib_file PARAMS ((export_type *, int));
531static bfd *make_head PARAMS ((void));
532static bfd *make_tail PARAMS ((void));
533static void gen_lib_file PARAMS ((void));
534static int pfunc PARAMS ((const void *, const void *));
535static int nfunc PARAMS ((const void *, const void *));
536static void remove_null_names PARAMS ((export_type **));
537static void dtab PARAMS ((export_type **));
538static void process_duplicates PARAMS ((export_type **));
539static void fill_ordinals PARAMS ((export_type **));
540static int alphafunc PARAMS ((const void *, const void *));
541static void mangle_defs PARAMS ((void));
faad4b47
ILT
542static void usage PARAMS ((FILE *, int));
543static void display PARAMS ((const char *, va_list));
061ed861
NC
544static void inform PARAMS ((const char *, ...));
545static void warn PARAMS ((const char *, ...));
546
547static void
faad4b47 548display (message, args)
061ed861
NC
549 const char * message;
550 va_list args;
551{
552 if (program_name != NULL)
553 fprintf (stderr, "%s: ", program_name);
554
555 vfprintf (stderr, message, args);
556
557 if (message [strlen (message) - 1] != '\n')
558 fputc ('\n', stderr);
559}
560
561
562static void
563#ifdef __STDC__
564inform (const char * message, ...)
565#else
566inform (message, va_alist)
567 const char * message;
568 va_dcl
569#endif
570{
571 va_list args;
572
573 if (!verbose)
574 return;
575
576#ifdef __STDC__
577 va_start (args, message);
578#else
579 va_start (args);
580#endif
581
faad4b47 582 display (message, args);
061ed861
NC
583
584 va_end (args);
585}
586
587static void
588#ifdef __STDC__
589warn (const char * message, ...)
590#else
591warn (message, va_alist)
592 const char * message;
593 va_dcl
594#endif
595{
596 va_list args;
597
598#ifdef __STDC__
599 va_start (args, message);
600#else
601 va_start (args);
602#endif
603
faad4b47 604 display (message, args);
061ed861
NC
605
606 va_end (args);
607}
a33f7359
ILT
608
609static const char *
531f86b4
SC
610rvaafter (machine)
611 int machine;
2757dc25 612{
f88ebc68
SC
613 switch (machine)
614 {
615 case MARM:
f88ebc68 616 case M386:
6d93c360 617 case MPPC:
061ed861
NC
618 case MTHUMB:
619 break;
620 default:
621 /* xgettext:c-format */
622 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
623 break;
f88ebc68 624 }
a33f7359 625 return "";
2757dc25
SC
626}
627
a33f7359 628static const char *
531f86b4
SC
629rvabefore (machine)
630 int machine;
2757dc25 631{
f88ebc68
SC
632 switch (machine)
633 {
634 case MARM:
f88ebc68 635 case M386:
6d93c360 636 case MPPC:
061ed861 637 case MTHUMB:
6d93c360 638 return ".rva\t";
061ed861
NC
639 default:
640 /* xgettext:c-format */
641 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
642 break;
f88ebc68 643 }
a33f7359 644 return "";
2757dc25 645}
199f5217 646
a33f7359 647static const char *
531f86b4 648asm_prefix (machine)
a33f7359 649 int machine;
199f5217
DE
650{
651 switch (machine)
652 {
653 case MARM:
061ed861
NC
654 case MPPC:
655 case MTHUMB:
656 break;
199f5217
DE
657 case M386:
658 return "_";
061ed861
NC
659 default:
660 /* xgettext:c-format */
661 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
662 break;
199f5217 663 }
a33f7359 664 return "";
199f5217 665}
a33f7359 666
765e60a9
SC
667#define ASM_BYTE mtable[machine].how_byte
668#define ASM_SHORT mtable[machine].how_short
669#define ASM_LONG mtable[machine].how_long
670#define ASM_TEXT mtable[machine].how_asciz
671#define ASM_C mtable[machine].how_comment
672#define ASM_JUMP mtable[machine].how_jump
673#define ASM_GLOBAL mtable[machine].how_global
674#define ASM_SPACE mtable[machine].how_space
fb257042 675#define ASM_ALIGN_SHORT mtable[machine].how_align_short
2757dc25
SC
676#define ASM_RVA_BEFORE rvabefore(machine)
677#define ASM_RVA_AFTER rvaafter(machine)
199f5217 678#define ASM_PREFIX asm_prefix(machine)
f051e1b0 679#define ASM_ALIGN_LONG mtable[machine].how_align_long
356c68ff
SC
680#define HOW_BFD_TARGET 0 /* always default*/
681#define HOW_BFD_ARCH mtable[machine].how_bfd_arch
682#define HOW_JTAB mtable[machine].how_jtab
683#define HOW_JTAB_SIZE mtable[machine].how_jtab_size
684#define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
765e60a9
SC
685static char **oav;
686
765e60a9
SC
687void
688process_def_file (name)
a33f7359 689 const char *name;
765e60a9 690{
20dec772 691 FILE *f = fopen (name, FOPEN_RT);
061ed861 692
765e60a9 693 if (!f)
061ed861
NC
694 /* xgettext:c-format */
695 fatal (_("Can't open def file: %s"), name);
765e60a9
SC
696
697 yyin = f;
698
061ed861
NC
699 /* xgettext:c-format */
700 inform (_("Processing def file: %s"), name);
701
765e60a9 702 yyparse ();
061ed861
NC
703
704 inform (_("Processed def file"));
765e60a9
SC
705}
706
707/**********************************************************************/
708
709/* Communications with the parser */
710
a33f7359 711static const char *d_name; /* Arg to NAME or LIBRARY */
765e60a9 712static int d_nfuncs; /* Number of functions exported */
f051e1b0
SC
713static int d_named_nfuncs; /* Number of named functions exported */
714static int d_low_ord; /* Lowest ordinal index */
715static int d_high_ord; /* Highest ordinal index */
765e60a9 716static export_type *d_exports; /*list of exported functions */
f051e1b0 717static export_type **d_exports_lexically; /* vector of exported functions in alpha order */
6f2d3212
SC
718static dlist_type *d_list; /* Descriptions */
719static dlist_type *a_list; /* Stuff to go in directives */
765e60a9
SC
720
721static int d_is_dll;
722static int d_is_exe;
723
c027e8b0 724int
a33f7359
ILT
725yyerror (err)
726 const char *err;
765e60a9 727{
061ed861
NC
728 /* xgettext:c-format */
729 warn (_("Syntax error in def file %s:%d\n"), def_file, linenumber);
730
356c68ff 731 return 0;
765e60a9
SC
732}
733
734void
c336631b 735def_exports (name, internal_name, ordinal, noname, constant, data)
a33f7359
ILT
736 const char *name;
737 const char *internal_name;
765e60a9
SC
738 int ordinal;
739 int noname;
740 int constant;
c336631b 741 int data;
765e60a9
SC
742{
743 struct export *p = (struct export *) xmalloc (sizeof (*p));
744
745 p->name = name;
b990c244 746 p->internal_name = internal_name ? internal_name : name;
765e60a9
SC
747 p->ordinal = ordinal;
748 p->constant = constant;
749 p->noname = noname;
c336631b 750 p->data = data;
765e60a9
SC
751 p->next = d_exports;
752 d_exports = p;
753 d_nfuncs++;
765e60a9
SC
754}
755
756void
757def_name (name, base)
a33f7359 758 const char *name;
765e60a9
SC
759 int base;
760{
061ed861
NC
761 /* xgettext:c-format */
762 inform (_("NAME: %s base: %x"), name, base);
763
765e60a9 764 if (d_is_dll)
061ed861
NC
765 warn (_("Can't have LIBRARY and NAME\n"));
766
765e60a9 767 d_name = name;
765e60a9
SC
768 d_is_exe = 1;
769}
770
771void
772def_library (name, base)
a33f7359 773 const char *name;
765e60a9
SC
774 int base;
775{
061ed861
NC
776 /* xgettext:c-format */
777 inform (_("LIBRARY: %s base: %x"), name, base);
778
765e60a9 779 if (d_is_exe)
061ed861
NC
780 warn (_("%s: Can't have LIBRARY and NAME\n"), program_name);
781
765e60a9 782 d_name = name;
765e60a9
SC
783 d_is_dll = 1;
784}
785
786void
787def_description (desc)
a33f7359 788 const char *desc;
765e60a9 789{
6f2d3212 790 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
a33f7359 791 d->text = xstrdup (desc);
765e60a9
SC
792 d->next = d_list;
793 d_list = d;
794}
795
2757dc25 796void
6f2d3212
SC
797new_directive (dir)
798 char *dir;
765e60a9 799{
6f2d3212 800 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
a33f7359 801 d->text = xstrdup (dir);
765e60a9
SC
802 d->next = a_list;
803 a_list = d;
804}
805
806void
a4e5fd18 807def_heapsize (reserve, commit)
765e60a9
SC
808 int reserve;
809 int commit;
810{
811 char b[200];
6f2d3212 812 if (commit > 0)
a4e5fd18 813 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
6f2d3212 814 else
a4e5fd18 815 sprintf (b, "-heap 0x%x ", reserve);
a33f7359 816 new_directive (xstrdup (b));
765e60a9
SC
817}
818
819void
a4e5fd18 820def_stacksize (reserve, commit)
765e60a9
SC
821 int reserve;
822 int commit;
823{
824 char b[200];
6f2d3212 825 if (commit > 0)
a4e5fd18 826 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
6f2d3212 827 else
a4e5fd18 828 sprintf (b, "-stack 0x%x ", reserve);
a33f7359 829 new_directive (xstrdup (b));
765e60a9
SC
830}
831
c027e8b0
ILT
832/* append_import simply adds the given import definition to the global
833 import_list. It is used by def_import. */
834
835static void
a4e5fd18 836append_import (symbol_name, dll_name, func_ordinal)
c027e8b0
ILT
837 const char *symbol_name;
838 const char *dll_name;
839 int func_ordinal;
840{
841 iheadtype **pq;
842 iheadtype *q;
843
844 for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
845 {
846 if (strcmp ((*pq)->dllname, dll_name) == 0)
847 {
848 q = *pq;
849 q->functail->next = xmalloc (sizeof (ifunctype));
850 q->functail = q->functail->next;
851 q->functail->ord = func_ordinal;
852 q->functail->name = xstrdup (symbol_name);
853 q->functail->next = NULL;
854 q->nfuncs++;
855 return;
856 }
857 }
858
859 q = xmalloc (sizeof (iheadtype));
860 q->dllname = xstrdup (dll_name);
861 q->nfuncs = 1;
862 q->funchead = xmalloc (sizeof (ifunctype));
863 q->functail = q->funchead;
864 q->next = NULL;
865 q->functail->name = xstrdup (symbol_name);
866 q->functail->ord = func_ordinal;
867 q->functail->next = NULL;
868
869 *pq = q;
870}
871
872/* def_import is called from within defparse.y when an IMPORT
873 declaration is encountered. Depending on the form of the
874 declaration, the module name may or may not need ".dll" to be
875 appended to it, the name of the function may be stored in internal
876 or entry, and there may or may not be an ordinal value associated
877 with it. */
a4e5fd18
BM
878
879/* A note regarding the parse modes:
c027e8b0
ILT
880 In defparse.y we have to accept import declarations which follow
881 any one of the following forms:
a4e5fd18
BM
882 <func_name_in_app> = <dll_name>.<func_name_in_dll>
883 <func_name_in_app> = <dll_name>.<number>
884 <dll_name>.<func_name_in_dll>
885 <dll_name>.<number>
c027e8b0
ILT
886 Furthermore, the dll's name may or may not end with ".dll", which
887 complicates the parsing a little. Normally the dll's name is
888 passed to def_import() in the "module" parameter, but when it ends
889 with ".dll" it gets passed in "module" sans ".dll" and that needs
890 to be reappended.
891
892 def_import gets five parameters:
893 APP_NAME - the name of the function in the application, if
a4e5fd18 894 present, or NULL if not present.
c027e8b0
ILT
895 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
896 DLLEXT - the extension of the dll, if present, NULL if not present.
897 ENTRY - the name of the function in the dll, if present, or NULL.
898 ORD_VAL - the numerical tag of the function in the dll, if present,
899 or NULL. Exactly one of <entry> or <ord_val> must be
900 present (i.e., not NULL). */
a4e5fd18 901
c027e8b0 902void
a4e5fd18 903def_import (app_name, module, dllext, entry, ord_val)
c027e8b0
ILT
904 const char *app_name;
905 const char *module;
906 const char *dllext;
907 const char *entry;
908 int ord_val;
909{
910 const char *application_name;
911 char *buf;
912
913 if (entry != NULL)
914 application_name = entry;
915 else
916 {
917 if (app_name != NULL)
918 application_name = app_name;
a4e5fd18 919 else
c027e8b0
ILT
920 application_name = "";
921 }
061ed861 922
c027e8b0
ILT
923 if (dllext != NULL)
924 {
925 buf = (char *) alloca (strlen (module) + strlen (dllext) + 2);
926 sprintf (buf, "%s.%s", module, dllext);
927 module = buf;
928 }
929
930 append_import (application_name, module, ord_val);
931}
765e60a9
SC
932
933void
934def_version (major, minor)
a33f7359
ILT
935 int major;
936 int minor;
765e60a9
SC
937{
938 printf ("VERSION %d.%d\n", major, minor);
939}
940
765e60a9
SC
941void
942def_section (name, attr)
a33f7359 943 const char *name;
765e60a9
SC
944 int attr;
945{
946 char buf[200];
6f2d3212 947 char atts[5];
765e60a9
SC
948 char *d = atts;
949 if (attr & 1)
6f2d3212 950 *d++ = 'R';
765e60a9
SC
951
952 if (attr & 2)
953 *d++ = 'W';
954 if (attr & 4)
955 *d++ = 'X';
956 if (attr & 8)
957 *d++ = 'S';
958 *d++ = 0;
959 sprintf (buf, "-attr %s %s", name, atts);
a33f7359 960 new_directive (xstrdup (buf));
765e60a9 961}
a33f7359 962
765e60a9
SC
963void
964def_code (attr)
965 int attr;
966{
967
6f2d3212 968 def_section ("CODE", attr);
765e60a9
SC
969}
970
971void
972def_data (attr)
973 int attr;
974{
6f2d3212 975 def_section ("DATA", attr);
765e60a9
SC
976}
977
765e60a9
SC
978/**********************************************************************/
979
a33f7359 980static void
2757dc25 981run (what, args)
a33f7359 982 const char *what;
2757dc25
SC
983 char *args;
984{
985 char *s;
c336631b 986 int pid, wait_status;
2757dc25 987 int i;
a33f7359 988 const char **argv;
c336631b
ILT
989 char *errmsg_fmt, *errmsg_arg;
990 char *temp_base = choose_temp_base ();
a33f7359 991
061ed861 992 inform ("run: %s %s\n", what, args);
2757dc25
SC
993
994 /* Count the args */
995 i = 0;
531f86b4 996 for (s = args; *s; s++)
2757dc25
SC
997 if (*s == ' ')
998 i++;
999 i++;
531f86b4 1000 argv = alloca (sizeof (char *) * (i + 3));
2757dc25
SC
1001 i = 0;
1002 argv[i++] = what;
1003 s = args;
531f86b4
SC
1004 while (1)
1005 {
061ed861
NC
1006 while (*s == ' ')
1007 ++s;
531f86b4
SC
1008 argv[i++] = s;
1009 while (*s != ' ' && *s != 0)
1010 s++;
1011 if (*s == 0)
1012 break;
1013 *s++ = 0;
1014 }
a33f7359 1015 argv[i++] = NULL;
2757dc25 1016
c336631b
ILT
1017 pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
1018 &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
356c68ff 1019
c336631b 1020 if (pid == -1)
2757dc25 1021 {
061ed861
NC
1022 inform (strerror (errno));
1023
1024 fatal (errmsg_fmt, errmsg_arg);
2757dc25 1025 }
c336631b 1026
061ed861
NC
1027 pid = pwait (pid, & wait_status, 0);
1028
c336631b 1029 if (pid == -1)
2757dc25 1030 {
061ed861
NC
1031 /* xgettext:c-format */
1032 fatal (_("wait: %s"), strerror (errno));
2757dc25 1033 }
c336631b 1034 else if (WIFSIGNALED (wait_status))
2757dc25 1035 {
061ed861
NC
1036 /* xgettext:c-format */
1037 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
c336631b
ILT
1038 }
1039 else if (WIFEXITED (wait_status))
1040 {
1041 if (WEXITSTATUS (wait_status) != 0)
061ed861
NC
1042 /* xgettext:c-format */
1043 warn (_("%s exited with status %d\n"),
1044 what, WEXITSTATUS (wait_status));
2757dc25 1045 }
c336631b
ILT
1046 else
1047 abort ();
2757dc25
SC
1048}
1049
faad4b47
ILT
1050/* Look for a list of symbols to export in the .drectve section of
1051 ABFD. Pass each one to def_exports. */
1052
a33f7359 1053static void
faad4b47 1054scan_drectve_symbols (abfd)
765e60a9
SC
1055 bfd *abfd;
1056{
061ed861
NC
1057 asection * s;
1058 int size;
1059 char * buf;
1060 char * p;
1061 char * e;
1062
199f5217 1063 /* Look for .drectve's */
061ed861
NC
1064 s = bfd_get_section_by_name (abfd, ".drectve");
1065
1066 if (s == NULL)
1067 return;
1068
1069 size = bfd_get_section_size_before_reloc (s);
1070 buf = xmalloc (size);
1071
1072 bfd_get_section_contents (abfd, s, buf, 0, size);
1073
1074 /* xgettext:c-format */
1075 inform (_("Sucking in info from .drective section in %s\n"),
1076 bfd_get_filename (abfd));
1077
1078 /* Search for -export: strings */
1079 p = buf;
1080 e = buf + size;
1081 while (p < e)
1082 {
1083 if (p[0] == '-'
1084 && strncmp (p, "-export:", 8) == 0)
765e60a9 1085 {
061ed861
NC
1086 char * name;
1087 char * c;
1088
1089 p += 8;
1090 name = p;
1091 while (p < e && *p != ' ' && *p != '-')
765e60a9 1092 p++;
061ed861
NC
1093 c = xmalloc (p - name + 1);
1094 memcpy (c, name, p - name);
1095 c[p - name] = 0;
1096 /* FIXME: The 5th arg is for the `constant' field.
1097 What should it be? Not that it matters since it's not
1098 currently useful. */
1099 def_exports (c, 0, -1, 0, 0, 0);
765e60a9 1100 }
061ed861
NC
1101 else
1102 p++;
765e60a9 1103 }
061ed861 1104 free (buf);
faad4b47
ILT
1105}
1106
1107/* Look through the symbols in MINISYMS, and add each one to list of
1108 symbols to export. */
1109
1110static void
1111scan_filtered_symbols (abfd, minisyms, symcount, size)
1112 bfd *abfd;
1113 PTR minisyms;
1114 long symcount;
1115 unsigned int size;
1116{
1117 asymbol *store;
1118 bfd_byte *from, *fromend;
1119
1120 store = bfd_make_empty_symbol (abfd);
1121 if (store == NULL)
1122 bfd_fatal (bfd_get_filename (abfd));
1123
1124 from = (bfd_byte *) minisyms;
1125 fromend = from + symcount * size;
1126 for (; from < fromend; from += size)
1127 {
1128 asymbol *sym;
1129 const char *symbol_name;
1130
1131 sym = bfd_minisymbol_to_symbol (abfd, false, from, store);
1132 if (sym == NULL)
1133 bfd_fatal (bfd_get_filename (abfd));
1134
1135 symbol_name = bfd_asymbol_name (sym);
1136 if (bfd_get_symbol_leading_char (abfd) == symbol_name[0])
1137 ++symbol_name;
1138
1139 def_exports (xstrdup (symbol_name), 0, -1, 0, 0, 0);
1140 }
1141}
1142
1143/* Add a list of symbols to exclude. */
6f2d3212 1144
faad4b47
ILT
1145static void
1146add_excludes (new_excludes)
1147 const char *new_excludes;
1148{
1149 char *local_copy;
1150 char *exclude_string;
1151
1152 local_copy = xstrdup (new_excludes);
1153
1154 exclude_string = strtok (local_copy, ",:");
1155 for (; exclude_string; exclude_string = strtok (NULL, ",:"))
1156 {
1157 struct string_list *new_exclude;
1158
1159 new_exclude = ((struct string_list *)
1160 xmalloc (sizeof (struct string_list)));
1161 new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2);
1162 /* FIXME: Is it always right to add a leading underscore? */
1163 sprintf (new_exclude->string, "_%s", exclude_string);
1164 new_exclude->next = excludes;
1165 excludes = new_exclude;
1166
1167 /* xgettext:c-format */
1168 inform (_("Excluding symbol: %s\n"), exclude_string);
1169 }
1170
1171 free (local_copy);
1172}
1173
1174/* See if STRING is on the list of symbols to exclude. */
1175
1176static boolean
1177match_exclude (string)
1178 const char *string;
1179{
1180 struct string_list *excl_item;
1181
1182 for (excl_item = excludes; excl_item; excl_item = excl_item->next)
1183 if (strcmp (string, excl_item->string) == 0)
1184 return true;
1185 return false;
1186}
1187
1188/* Add the default list of symbols to exclude. */
1189
1190static void
1191set_default_excludes (void)
1192{
1193 add_excludes (default_excludes);
1194}
1195
1196/* Choose which symbols to export. */
1197
1198static long
1199filter_symbols (abfd, minisyms, symcount, size)
1200 bfd *abfd;
1201 PTR minisyms;
1202 long symcount;
1203 unsigned int size;
1204{
1205 bfd_byte *from, *fromend, *to;
1206 asymbol *store;
1207
1208 store = bfd_make_empty_symbol (abfd);
1209 if (store == NULL)
1210 bfd_fatal (bfd_get_filename (abfd));
1211
1212 from = (bfd_byte *) minisyms;
1213 fromend = from + symcount * size;
1214 to = (bfd_byte *) minisyms;
1215
1216 for (; from < fromend; from += size)
1217 {
1218 int keep = 0;
1219 asymbol *sym;
1220
1221 sym = bfd_minisymbol_to_symbol (abfd, false, (const PTR) from, store);
1222 if (sym == NULL)
1223 bfd_fatal (bfd_get_filename (abfd));
1224
1225 /* Check for external and defined only symbols. */
1226 keep = (((sym->flags & BSF_GLOBAL) != 0
1227 || (sym->flags & BSF_WEAK) != 0
1228 || bfd_is_com_section (sym->section))
1229 && ! bfd_is_und_section (sym->section));
1230
1231 keep = keep && ! match_exclude (sym->name);
1232
1233 if (keep)
1234 {
1235 memcpy (to, from, size);
1236 to += size;
1237 }
1238 }
1239
1240 return (to - (bfd_byte *) minisyms) / size;
1241}
1242
1243/* Export all symbols in ABFD, except for ones we were told not to
1244 export. */
1245
1246static void
1247scan_all_symbols (abfd)
1248 bfd *abfd;
1249{
1250 long symcount;
1251 PTR minisyms;
1252 unsigned int size;
1253
1254 if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
1255 {
1256 /* xgettext:c-format */
1257 warn (_("%s: no symbols\n"), bfd_get_filename (abfd));
1258 return;
1259 }
1260
1261 symcount = bfd_read_minisymbols (abfd, false, &minisyms, &size);
1262 if (symcount < 0)
1263 bfd_fatal (bfd_get_filename (abfd));
1264
1265 if (symcount == 0)
1266 {
1267 /* xgettext:c-format */
1268 warn (_("%s: no symbols\n"), bfd_get_filename (abfd));
1269 return;
1270 }
1271
1272 /* Discard the symbols we don't want to export. It's OK to do this
1273 in place; we'll free the storage anyway. */
1274
1275 symcount = filter_symbols (abfd, minisyms, symcount, size);
1276 scan_filtered_symbols (abfd, minisyms, symcount, size);
1277
1278 free (minisyms);
1279}
1280
1281/* Look at the object file to decide which symbols to export. */
1282
1283static void
1284scan_open_obj_file (abfd)
1285 bfd *abfd;
1286{
1287 if (export_all_symbols)
1288 scan_all_symbols (abfd);
1289 else
1290 scan_drectve_symbols (abfd);
1291
061ed861 1292 /* FIXME: we ought to read in and block out the base relocations */
6f2d3212 1293
faad4b47
ILT
1294 /* xgettext:c-format */
1295 inform (_("%s: Done reading %s\n"), bfd_get_filename (abfd));
765e60a9
SC
1296}
1297
a33f7359 1298static void
765e60a9 1299scan_obj_file (filename)
a33f7359 1300 const char *filename;
765e60a9 1301{
061ed861 1302 bfd * f = bfd_openr (filename, 0);
765e60a9
SC
1303
1304 if (!f)
061ed861
NC
1305 /* xgettext:c-format */
1306 fatal (_("Unable to open object file: %s"), filename);
1307
1308 /* xgettext:c-format */
1309 inform (_("Scanning object file %s"), filename);
1310
765e60a9
SC
1311 if (bfd_check_format (f, bfd_archive))
1312 {
1313 bfd *arfile = bfd_openr_next_archived_file (f, 0);
1314 while (arfile)
1315 {
1316 if (bfd_check_format (arfile, bfd_object))
1317 scan_open_obj_file (arfile);
1318 bfd_close (arfile);
1319 arfile = bfd_openr_next_archived_file (f, arfile);
1320 }
1321 }
356c68ff 1322 else if (bfd_check_format (f, bfd_object))
765e60a9
SC
1323 {
1324 scan_open_obj_file (f);
1325 }
1326
1327 bfd_close (f);
1328}
1329
1330/**********************************************************************/
1331
a33f7359 1332static void
765e60a9 1333dump_def_info (f)
6f2d3212 1334 FILE *f;
765e60a9
SC
1335{
1336 int i;
1337 export_type *exp;
6f2d3212
SC
1338 fprintf (f, "%s ", ASM_C);
1339 for (i = 0; oav[i]; i++)
1340 fprintf (f, "%s ", oav[i]);
1341 fprintf (f, "\n");
765e60a9
SC
1342 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1343 {
c336631b 1344 fprintf (f, "%s %d = %s %s @ %d %s%s%s\n",
765e60a9
SC
1345 ASM_C,
1346 i,
6f2d3212
SC
1347 exp->name,
1348 exp->internal_name,
b990c244 1349 exp->ordinal,
765e60a9 1350 exp->noname ? "NONAME " : "",
c336631b
ILT
1351 exp->constant ? "CONSTANT" : "",
1352 exp->data ? "DATA" : "");
765e60a9
SC
1353 }
1354}
a33f7359 1355
765e60a9
SC
1356/* Generate the .exp file */
1357
a33f7359 1358static int
6f2d3212 1359sfunc (a, b)
a33f7359
ILT
1360 const void *a;
1361 const void *b;
6f2d3212 1362{
a33f7359 1363 return *(const long *) a - *(const long *) b;
6f2d3212
SC
1364}
1365
2757dc25 1366static void
6f2d3212
SC
1367flush_page (f, need, page_addr, on_page)
1368 FILE *f;
a33f7359 1369 long *need;
356c68ff 1370 int page_addr;
6f2d3212
SC
1371 int on_page;
1372{
1373 int i;
f051e1b0 1374
6f2d3212 1375 /* Flush this page */
4828cdba
DE
1376 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1377 ASM_LONG,
ee473c97 1378 page_addr,
6f2d3212
SC
1379 ASM_C);
1380 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1381 ASM_LONG,
1382 (on_page * 2) + (on_page & 1) * 2 + 8,
1383 ASM_C);
1384 for (i = 0; i < on_page; i++)
1385 {
a33f7359 1386 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (need[i] - page_addr) | 0x3000);
6f2d3212
SC
1387 }
1388 /* And padding */
1389 if (on_page & 1)
1390 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
6f2d3212
SC
1391}
1392
a33f7359 1393static void
531f86b4
SC
1394gen_def_file ()
1395{
1396 int i;
1397 export_type *exp;
356c68ff 1398
061ed861
NC
1399 inform (_("Adding exports to output file"));
1400
531f86b4
SC
1401 fprintf (output_def, ";");
1402 for (i = 0; oav[i]; i++)
1403 fprintf (output_def, " %s", oav[i]);
1404
1405 fprintf (output_def, "\nEXPORTS\n");
356c68ff 1406
531f86b4
SC
1407 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1408 {
356c68ff 1409 char *quote = strchr (exp->name, '.') ? "\"" : "";
faad4b47
ILT
1410 char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
1411
c336631b 1412 fprintf (output_def, "\t%s%s%s @ %d%s%s ; %s\n",
356c68ff 1413 quote,
531f86b4 1414 exp->name,
356c68ff 1415 quote,
531f86b4 1416 exp->ordinal,
356c68ff 1417 exp->noname ? " NONAME" : "",
c336631b 1418 exp->data ? " DATA" : "",
faad4b47
ILT
1419 res ? res : "");
1420 if (res)
1421 free (res);
531f86b4 1422 }
061ed861
NC
1423
1424 inform (_("Added exports to output file"));
531f86b4 1425}
a33f7359 1426
c027e8b0
ILT
1427/* generate_idata_ofile generates the portable assembly source code
1428 for the idata sections. It appends the source code to the end of
1429 the file. */
1430
1431static void
1432generate_idata_ofile (filvar)
1433 FILE *filvar;
1434{
1435 iheadtype *headptr;
1436 ifunctype *funcptr;
1437 int headindex;
1438 int funcindex;
1439 int nheads;
1440
1441 if (import_list == NULL)
1442 return;
1443
1444 fprintf (filvar, "%s Import data sections\n", ASM_C);
1445 fprintf (filvar, "\n\t.section\t.idata$2\n");
1446 fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1447 fprintf (filvar, "doi_idata:\n");
1448
1449 nheads = 0;
1450 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1451 {
1452 fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1453 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
1454 ASM_C, headptr->dllname);
1455 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1456 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1457 fprintf (filvar, "\t%sdllname%d%s\n",
1458 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1459 fprintf (filvar, "\t%slisttwo%d%s\n\n",
1460 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1461 nheads++;
1462 }
1463
1464 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1465 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1466 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
1467 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1468 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1469
1470 fprintf (filvar, "\n\t.section\t.idata$4\n");
1471 headindex = 0;
1472 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1473 {
1474 fprintf (filvar, "listone%d:\n", headindex);
1475 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1476 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1477 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1478 fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1479 headindex++;
1480 }
1481
1482 fprintf (filvar, "\n\t.section\t.idata$5\n");
1483 headindex = 0;
1484 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1485 {
1486 fprintf (filvar, "listtwo%d:\n", headindex);
1487 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1488 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1489 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1490 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1491 headindex++;
1492 }
1493
1494 fprintf (filvar, "\n\t.section\t.idata$6\n");
1495 headindex = 0;
1496 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1497 {
1498 funcindex = 0;
1499 for (funcptr = headptr->funchead; funcptr != NULL;
1500 funcptr = funcptr->next)
1501 {
1502 fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
1503 fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
1504 ((funcptr->ord) & 0xFFFF));
1505 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name);
1506 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1507 funcindex++;
1508 }
1509 headindex++;
1510 }
1511
1512 fprintf (filvar, "\n\t.section\t.idata$7\n");
1513 headindex = 0;
1514 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1515 {
1516 fprintf (filvar,"dllname%d:\n", headindex);
1517 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
1518 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1519 headindex++;
1520 }
1521}
a4e5fd18 1522
a33f7359 1523static void
765e60a9
SC
1524gen_exp_file ()
1525{
1526 FILE *f;
765e60a9
SC
1527 int i;
1528 export_type *exp;
1529 dlist_type *dl;
356c68ff 1530
061ed861
NC
1531 /* xgettext:c-format */
1532 inform (_("Generating export file: %s\n"), exp_name);
1533
1534 f = fopen (TMP_ASM, FOPEN_WT);
765e60a9 1535 if (!f)
061ed861
NC
1536 /* xgettext:c-format */
1537 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
1538
1539 /* xgettext:c-format */
1540 inform (_("Opened temporary file: %s"), TMP_ASM);
6f2d3212 1541
765e60a9 1542 dump_def_info (f);
061ed861 1543
531f86b4
SC
1544 if (d_exports)
1545 {
1546 fprintf (f, "\t.section .edata\n\n");
1547 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
a33f7359
ILT
1548 fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG, (long) time(0),
1549 ASM_C);
531f86b4
SC
1550 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
1551 fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
f051e1b0
SC
1552 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
1553
1554
1555 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
1556 fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
1557 ASM_C,
1558 d_named_nfuncs, d_low_ord, d_high_ord);
1559 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
1560 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
531f86b4 1561 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
f051e1b0 1562
c027e8b0 1563 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
f051e1b0
SC
1564 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1565
531f86b4
SC
1566 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1567
1568 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
1569
f051e1b0
SC
1570
1571 fprintf(f,"%s Export address Table\n", ASM_C);
1572 fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
531f86b4 1573 fprintf (f, "afuncs:\n");
f051e1b0
SC
1574 i = d_low_ord;
1575
531f86b4
SC
1576 for (exp = d_exports; exp; exp = exp->next)
1577 {
531f86b4
SC
1578 if (exp->ordinal != i)
1579 {
c027e8b0 1580#if 0
f051e1b0
SC
1581 fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
1582 ASM_SPACE,
531f86b4 1583 (exp->ordinal - i) * 4,
f051e1b0 1584 ASM_C,
531f86b4
SC
1585 i, exp->ordinal - 1);
1586 i = exp->ordinal;
6f2d3212 1587#endif
f051e1b0
SC
1588 while (i < exp->ordinal)
1589 {
1590 fprintf(f,"\t%s\t0\n", ASM_LONG);
1591 i++;
1592 }
1593 }
531f86b4
SC
1594 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
1595 ASM_PREFIX,
1596 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1597 i++;
1598 }
f88ebc68 1599
f051e1b0 1600 fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
531f86b4 1601 fprintf (f, "anames:\n");
f051e1b0 1602
356c68ff 1603 for (i = 0; (exp = d_exports_lexically[i]); i++)
531f86b4 1604 {
f051e1b0 1605 if (!exp->noname || show_allnames)
061ed861
NC
1606 fprintf (f, "\t%sn%d%s\n",
1607 ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
531f86b4 1608 }
f88ebc68 1609
f051e1b0 1610 fprintf (f,"%s Export Oridinal Table\n", ASM_C);
531f86b4 1611 fprintf (f, "anords:\n");
356c68ff 1612 for (i = 0; (exp = d_exports_lexically[i]); i++)
f051e1b0
SC
1613 {
1614 if (!exp->noname || show_allnames)
1615 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
1616 }
f88ebc68 1617
f051e1b0 1618 fprintf(f,"%s Export Name Table\n", ASM_C);
356c68ff 1619 for (i = 0; (exp = d_exports_lexically[i]); i++)
f051e1b0 1620 if (!exp->noname || show_allnames)
061ed861
NC
1621 fprintf (f, "n%d: %s \"%s\"\n",
1622 exp->ordinal, ASM_TEXT, exp->name);
f88ebc68 1623
531f86b4
SC
1624 if (a_list)
1625 {
1626 fprintf (f, "\t.section .drectve\n");
1627 for (dl = a_list; dl; dl = dl->next)
1628 {
1629 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1630 }
1631 }
1632 if (d_list)
1633 {
1634 fprintf (f, "\t.section .rdata\n");
1635 for (dl = d_list; dl; dl = dl->next)
1636 {
1637 char *p;
1638 int l;
1639 /* We dont output as ascii 'cause there can
1640 be quote characters in the string */
f88ebc68 1641
531f86b4
SC
1642 l = 0;
1643 for (p = dl->text; *p; p++)
1644 {
1645 if (l == 0)
1646 fprintf (f, "\t%s\t", ASM_BYTE);
1647 else
1648 fprintf (f, ",");
1649 fprintf (f, "%d", *p);
1650 if (p[1] == 0)
1651 {
1652 fprintf (f, ",0\n");
1653 break;
1654 }
1655 if (++l == 10)
1656 {
1657 fprintf (f, "\n");
1658 l = 0;
1659 }
1660 }
1661 }
1662 }
1663 }
199f5217
DE
1664
1665
1666 /* Add to the output file a way of getting to the exported names
1667 without using the import library. */
1668 if (add_indirect)
1669 {
531f86b4 1670 fprintf (f, "\t.section\t.rdata\n");
199f5217 1671 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
f051e1b0 1672 if (!exp->noname || show_allnames)
531f86b4 1673 {
9d04d618
TT
1674 /* We use a single underscore for MS compatibility, and a
1675 double underscore for backward compatibility with old
1676 cygwin releases. */
531f86b4 1677 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
9d04d618 1678 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
531f86b4 1679 fprintf (f, "__imp_%s:\n", exp->name);
9d04d618 1680 fprintf (f, "_imp__%s:\n", exp->name);
531f86b4
SC
1681 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1682 }
199f5217
DE
1683 }
1684
6f2d3212
SC
1685 /* Dump the reloc section if a base file is provided */
1686 if (base_file)
1687 {
1688 int addr;
1689 long need[PAGE_SIZE];
1690 long page_addr;
1691 int numbytes;
1692 int num_entries;
1693 long *copy;
1694 int j;
1695 int on_page;
531f86b4
SC
1696 fprintf (f, "\t.section\t.init\n");
1697 fprintf (f, "lab:\n");
199f5217 1698
6f2d3212
SC
1699 fseek (base_file, 0, SEEK_END);
1700 numbytes = ftell (base_file);
1701 fseek (base_file, 0, SEEK_SET);
a33f7359 1702 copy = xmalloc (numbytes);
6f2d3212
SC
1703 fread (copy, 1, numbytes, base_file);
1704 num_entries = numbytes / sizeof (long);
1705
6f2d3212 1706
531f86b4
SC
1707 fprintf (f, "\t.section\t.reloc\n");
1708 if (num_entries)
1709 {
f051e1b0 1710 int src;
356c68ff 1711 int dst = 0;
f051e1b0
SC
1712 int last = -1;
1713 qsort (copy, num_entries, sizeof (long), sfunc);
1714 /* Delete duplcates */
1715 for (src = 0; src < num_entries; src++)
1716 {
c027e8b0 1717 if (last != copy[src])
f051e1b0
SC
1718 last = copy[dst++] = copy[src];
1719 }
1720 num_entries = dst;
531f86b4
SC
1721 addr = copy[0];
1722 page_addr = addr & PAGE_MASK; /* work out the page addr */
1723 on_page = 0;
1724 for (j = 0; j < num_entries; j++)
1725 {
1726 addr = copy[j];
1727 if ((addr & PAGE_MASK) != page_addr)
1728 {
1729 flush_page (f, need, page_addr, on_page);
1730 on_page = 0;
1731 page_addr = addr & PAGE_MASK;
1732 }
1733 need[on_page++] = addr;
1734 }
1735 flush_page (f, need, page_addr, on_page);
1736
356c68ff 1737/* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
531f86b4 1738 }
765e60a9 1739 }
6f2d3212 1740
c027e8b0 1741 generate_idata_ofile (f);
a4e5fd18 1742
765e60a9 1743 fclose (f);
2757dc25
SC
1744
1745 /* assemble the file */
061ed861
NC
1746 sprintf (outfile, "%s -o %s %s", as_flags, exp_name, TMP_ASM);
1747
1748#ifdef DLLTOOL_ARM
1749 if (interwork)
1750 strcat (outfile, " -mthumb-interwork");
1751#endif
1752
2757dc25 1753 run (as_name, outfile);
061ed861 1754
531f86b4 1755 if (dontdeltemps == 0)
061ed861
NC
1756 unlink (TMP_ASM);
1757
1758 inform (_("Generated exports file"));
765e60a9
SC
1759}
1760
a33f7359
ILT
1761static const char *
1762xlate (name)
1763 const char *name;
6f2d3212 1764{
531f86b4
SC
1765 if (add_underscore)
1766 {
a33f7359 1767 char *copy = xmalloc (strlen (name) + 2);
531f86b4
SC
1768 copy[0] = '_';
1769 strcpy (copy + 1, name);
1770 name = copy;
1771 }
00289839 1772
2757dc25
SC
1773 if (killat)
1774 {
1775 char *p;
1776 p = strchr (name, '@');
1777 if (p)
1778 *p = 0;
1779 }
6f2d3212
SC
1780 return name;
1781}
1782
765e60a9 1783/**********************************************************************/
f051e1b0 1784
faad4b47
ILT
1785#if 0
1786
a33f7359
ILT
1787static void
1788dump_iat (f, exp)
1789 FILE *f;
1790 export_type *exp;
f051e1b0 1791{
c027e8b0 1792 if (exp->noname && !show_allnames )
f051e1b0
SC
1793 {
1794 fprintf (f, "\t%s\t0x%08x\n",
1795 ASM_LONG,
1796 exp->ordinal | 0x80000000); /* hint or orindal ?? */
1797 }
1798 else
1799 {
1800 fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
1801 exp->ordinal,
1802 ASM_RVA_AFTER);
1803 }
1804}
765e60a9 1805
faad4b47
ILT
1806#endif
1807
c027e8b0 1808typedef struct
356c68ff
SC
1809{
1810 int id;
1811 const char *name;
1812 int flags;
b10f8e5e 1813 int align;
356c68ff
SC
1814 asection *sec;
1815 asymbol *sym;
1816 asymbol **sympp;
1817 int size;
1818 unsigned char *data;
1819} sinfo;
1820
b10f8e5e
KK
1821#ifndef DLLTOOL_PPC
1822
356c68ff
SC
1823#define TEXT 0
1824#define DATA 1
1825#define BSS 2
1826#define IDATA7 3
1827#define IDATA5 4
1828#define IDATA4 5
1829#define IDATA6 6
b10f8e5e 1830
356c68ff
SC
1831#define NSECS 7
1832
c027e8b0 1833static sinfo secdata[NSECS] =
356c68ff 1834{
a33f7359 1835 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 2},
b10f8e5e
KK
1836 { DATA, ".data", SEC_DATA, 2},
1837 { BSS, ".bss", 0, 2},
1838 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1839 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1840 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1841 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}
1842};
1843
c027e8b0 1844#else
b10f8e5e
KK
1845
1846/* Sections numbered to make the order the same as other PowerPC NT */
1847/* compilers. This also keeps funny alignment thingies from happening. */
1848#define TEXT 0
1849#define PDATA 1
1850#define RDATA 2
1851#define IDATA5 3
1852#define IDATA4 4
1853#define IDATA6 5
1854#define IDATA7 6
1855#define DATA 7
1856#define BSS 8
2757dc25 1857
b10f8e5e 1858#define NSECS 9
6f2d3212 1859
c027e8b0 1860static sinfo secdata[NSECS] =
b10f8e5e
KK
1861{
1862 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
1863 { PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
a33f7359 1864 { RDATA, ".reldata", SEC_HAS_CONTENTS, 2},
b10f8e5e
KK
1865 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1866 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1867 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1},
1868 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1869 { DATA, ".data", SEC_DATA, 2},
1870 { BSS, ".bss", 0, 2}
356c68ff 1871};
b10f8e5e
KK
1872
1873#endif
1874
356c68ff 1875/*
9d04d618
TT
1876This is what we're trying to make. We generate the imp symbols with
1877both single and double underscores, for compatibility.
356c68ff
SC
1878
1879 .text
1880 .global _GetFileVersionInfoSizeW@8
1881 .global __imp_GetFileVersionInfoSizeW@8
1882_GetFileVersionInfoSizeW@8:
1883 jmp * __imp_GetFileVersionInfoSizeW@8
1884 .section .idata$7 # To force loading of head
1885 .long __version_a_head
1886# Import Address Table
1887 .section .idata$5
1888__imp_GetFileVersionInfoSizeW@8:
1889 .rva ID2
1890
1891# Import Lookup Table
1892 .section .idata$4
1893 .rva ID2
1894# Hint/Name table
1895 .section .idata$6
1896ID2: .short 2
1897 .asciz "GetFileVersionInfoSizeW"
1898
b10f8e5e
KK
1899
1900For the PowerPC, here's the variation on the above scheme:
1901
c027e8b0 1902# Rather than a simple "jmp *", the code to get to the dll function
b10f8e5e
KK
1903# looks like:
1904 .text
1905 lwz r11,[tocv]__imp_function_name(r2)
1906# RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
1907 lwz r12,0(r11)
1908 stw r2,4(r1)
1909 mtctr r12
1910 lwz r2,4(r11)
1911 bctr
356c68ff
SC
1912*/
1913
b10f8e5e
KK
1914static char *
1915make_label (prefix, name)
1916 const char *prefix;
1917 const char *name;
356c68ff
SC
1918{
1919 int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
1920 char *copy = xmalloc (len +1 );
1921 strcpy (copy, ASM_PREFIX);
1922 strcat (copy, prefix);
1923 strcat (copy, name);
1924 return copy;
1925}
b10f8e5e 1926
356c68ff
SC
1927static bfd *
1928make_one_lib_file (exp, i)
b10f8e5e
KK
1929 export_type *exp;
1930 int i;
356c68ff 1931{
061ed861 1932#if 0
765e60a9 1933 {
356c68ff
SC
1934 FILE *f;
1935 char *prefix="d";
2757dc25 1936 sprintf (outfile, "%ss%d.s", prefix, i);
20dec772 1937 f = fopen (outfile, FOPEN_WT);
2757dc25 1938 fprintf (f, "\t.text\n");
199f5217 1939 fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name);
f88ebc68 1940 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
9d04d618 1941 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
199f5217
DE
1942 fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
1943 exp->name, ASM_JUMP, exp->name);
2757dc25 1944
f88ebc68 1945 fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
356c68ff 1946 fprintf (f, "\t%s\t%s\n", ASM_LONG, head_label);
2757dc25
SC
1947
1948
f051e1b0
SC
1949 fprintf (f,"%s Import Address Table\n", ASM_C);
1950
1951 fprintf (f, "\t.section .idata$5\n");
6f2d3212 1952 fprintf (f, "__imp_%s:\n", exp->name);
9d04d618 1953 fprintf (f, "_imp__%s:\n", exp->name);
2757dc25 1954
f051e1b0
SC
1955 dump_iat (f, exp);
1956
1957 fprintf (f, "\n%s Import Lookup Table\n", ASM_C);
2757dc25 1958 fprintf (f, "\t.section .idata$4\n");
2757dc25 1959
f051e1b0
SC
1960 dump_iat (f, exp);
1961
c027e8b0 1962 if(!exp->noname || show_allnames)
f051e1b0
SC
1963 {
1964 fprintf (f, "%s Hint/Name table\n", ASM_C);
1965 fprintf (f, "\t.section .idata$6\n");
c027e8b0 1966 fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
f051e1b0
SC
1967 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
1968 }
2757dc25 1969
2757dc25
SC
1970 fclose (f);
1971
061ed861
NC
1972 sprintf (outfile, "%s -o %ss%d.o %ss%d.s",
1973 as_flags, prefix, i, prefix, i);
2757dc25 1974
061ed861
NC
1975#ifdef DLLTOOL_ARM
1976 if (interwork)
1977 strcat (outfile, " -mthumb-interwork");
1978#endif
1979
2757dc25 1980 run (as_name, outfile);
765e60a9 1981 }
061ed861 1982#else /* if 0 */
356c68ff 1983 {
061ed861
NC
1984 bfd * abfd;
1985 asymbol * exp_label;
1986 asymbol * iname;
1987 asymbol * iname2;
1988 asymbol * iname_lab;
1989 asymbol ** iname_lab_pp;
1990 asymbol ** iname_pp;
b10f8e5e 1991#ifdef DLLTOOL_PPC
061ed861
NC
1992 asymbol ** fn_pp;
1993 asymbol ** toc_pp;
1994#define EXTRA 2
b10f8e5e 1995#endif
061ed861
NC
1996#ifndef EXTRA
1997#define EXTRA 0
a33f7359 1998#endif
061ed861 1999 asymbol * ptrs[NSECS + 4 + EXTRA + 1];
b10f8e5e 2000
061ed861
NC
2001 char * outname = xmalloc (10);
2002 int oidx = 0;
356c68ff 2003
061ed861
NC
2004
2005 sprintf (outname, "%s%d.o", TMP_STUB, i);
2006
356c68ff 2007 abfd = bfd_openw (outname, HOW_BFD_TARGET);
061ed861 2008
356c68ff 2009 if (!abfd)
061ed861
NC
2010 /* xgettext:c-format */
2011 fatal (_("bfd_open failed open stub file: %s"), outname);
356c68ff 2012
061ed861
NC
2013 /* xgettext:c-format */
2014 inform (_("Creating stub file: %s"), outname);
2015
356c68ff
SC
2016 bfd_set_format (abfd, bfd_object);
2017 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
2018
061ed861
NC
2019#ifdef DLLTOOL_ARM
2020 if (interwork)
2021 bfd_set_private_flags (abfd, F_INTERWORK);
2022#endif
2023
b10f8e5e 2024 /* First make symbols for the sections */
356c68ff
SC
2025 for (i = 0; i < NSECS; i++)
2026 {
2027 sinfo *si = secdata + i;
2028 if (si->id != i)
2029 abort();
2030 si->sec = bfd_make_section_old_way (abfd, si->name);
c027e8b0 2031 bfd_set_section_flags (abfd,
356c68ff
SC
2032 si->sec,
2033 si->flags);
c027e8b0 2034
b10f8e5e 2035 bfd_set_section_alignment(abfd, si->sec, si->align);
356c68ff 2036 si->sec->output_section = si->sec;
b10f8e5e 2037 si->sym = bfd_make_empty_symbol(abfd);
356c68ff
SC
2038 si->sym->name = si->sec->name;
2039 si->sym->section = si->sec;
2040 si->sym->flags = BSF_LOCAL;
2041 si->sym->value = 0;
2042 ptrs[oidx] = si->sym;
2043 si->sympp = ptrs + oidx;
c336631b
ILT
2044 si->size = 0;
2045 si->data = NULL;
356c68ff
SC
2046
2047 oidx++;
2048 }
2049
c336631b
ILT
2050 if (! exp->data)
2051 {
2052 exp_label = bfd_make_empty_symbol (abfd);
2053 exp_label->name = make_label ("", exp->name);
b10f8e5e 2054
c336631b
ILT
2055 /* On PowerPC, the function name points to a descriptor in
2056 the rdata section, the first element of which is a
2057 pointer to the code (..function_name), and the second
2058 points to the .toc */
a33f7359 2059#ifdef DLLTOOL_PPC
c336631b
ILT
2060 if (machine == MPPC)
2061 exp_label->section = secdata[RDATA].sec;
2062 else
a33f7359 2063#endif
c336631b 2064 exp_label->section = secdata[TEXT].sec;
b10f8e5e 2065
c336631b
ILT
2066 exp_label->flags = BSF_GLOBAL;
2067 exp_label->value = 0;
356c68ff 2068
061ed861
NC
2069#ifdef DLLTOOL_ARM
2070 if (machine == MTHUMB)
2071 bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXT);
2072#endif
c336631b
ILT
2073 ptrs[oidx++] = exp_label;
2074 }
356c68ff 2075
9d04d618
TT
2076 /* Generate imp symbols with one underscore for Microsoft
2077 compatibility, and with two underscores for backward
2078 compatibility with old versions of cygwin. */
356c68ff 2079 iname = bfd_make_empty_symbol(abfd);
356c68ff 2080 iname->name = make_label ("__imp_", exp->name);
356c68ff
SC
2081 iname->section = secdata[IDATA5].sec;
2082 iname->flags = BSF_GLOBAL;
2083 iname->value = 0;
2084
9d04d618
TT
2085 iname2 = bfd_make_empty_symbol(abfd);
2086 iname2->name = make_label ("_imp__", exp->name);
2087 iname2->section = secdata[IDATA5].sec;
2088 iname2->flags = BSF_GLOBAL;
2089 iname2->value = 0;
356c68ff
SC
2090
2091 iname_lab = bfd_make_empty_symbol(abfd);
2092
2093 iname_lab->name = head_label;
2094 iname_lab->section = (asection *)&bfd_und_section;
2095 iname_lab->flags = 0;
2096 iname_lab->value = 0;
2097
2098
b10f8e5e 2099 iname_pp = ptrs + oidx;
356c68ff 2100 ptrs[oidx++] = iname;
9d04d618 2101 ptrs[oidx++] = iname2;
b10f8e5e 2102
356c68ff
SC
2103 iname_lab_pp = ptrs + oidx;
2104 ptrs[oidx++] = iname_lab;
b10f8e5e
KK
2105
2106#ifdef DLLTOOL_PPC
2107 /* The symbol refering to the code (.text) */
a33f7359
ILT
2108 {
2109 asymbol *function_name;
b10f8e5e 2110
a33f7359
ILT
2111 function_name = bfd_make_empty_symbol(abfd);
2112 function_name->name = make_label ("..", exp->name);
2113 function_name->section = secdata[TEXT].sec;
2114 function_name->flags = BSF_GLOBAL;
2115 function_name->value = 0;
2116
2117 fn_pp = ptrs + oidx;
2118 ptrs[oidx++] = function_name;
2119 }
b10f8e5e
KK
2120
2121 /* The .toc symbol */
a33f7359
ILT
2122 {
2123 asymbol *toc_symbol; /* The .toc symbol */
2124
061ed861 2125 toc_symbol = bfd_make_empty_symbol (abfd);
a33f7359
ILT
2126 toc_symbol->name = make_label (".", "toc");
2127 toc_symbol->section = (asection *)&bfd_und_section;
2128 toc_symbol->flags = BSF_GLOBAL;
2129 toc_symbol->value = 0;
2130
2131 toc_pp = ptrs + oidx;
2132 ptrs[oidx++] = toc_symbol;
2133 }
b10f8e5e 2134#endif
061ed861 2135
356c68ff
SC
2136 ptrs[oidx] = 0;
2137
2138 for (i = 0; i < NSECS; i++)
2139 {
2140 sinfo *si = secdata + i;
2141 asection *sec = si->sec;
2142 arelent *rel;
2143 arelent **rpp;
2144
c027e8b0 2145 switch (i)
356c68ff
SC
2146 {
2147 case TEXT:
c336631b
ILT
2148 if (! exp->data)
2149 {
2150 si->size = HOW_JTAB_SIZE;
2151 si->data = xmalloc (HOW_JTAB_SIZE);
2152 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
c027e8b0 2153
061ed861 2154 /* add the reloc into idata$5 */
c336631b 2155 rel = xmalloc (sizeof (arelent));
061ed861 2156
c336631b
ILT
2157 rpp = xmalloc (sizeof (arelent *) * 2);
2158 rpp[0] = rel;
2159 rpp[1] = 0;
061ed861 2160
c336631b
ILT
2161 rel->address = HOW_JTAB_ROFF;
2162 rel->addend = 0;
b10f8e5e 2163
c336631b
ILT
2164 if (machine == MPPC)
2165 {
c027e8b0 2166 rel->howto = bfd_reloc_type_lookup (abfd,
c336631b
ILT
2167 BFD_RELOC_16_GOTOFF);
2168 rel->sym_ptr_ptr = iname_pp;
2169 }
2170 else
2171 {
2172 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2173 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2174 }
2175 sec->orelocation = rpp;
2176 sec->reloc_count = 1;
b10f8e5e 2177 }
356c68ff
SC
2178 break;
2179 case IDATA4:
2180 case IDATA5:
2181 /* An idata$4 or idata$5 is one word long, and has an
2182 rva to idata$6 */
c027e8b0 2183
356c68ff
SC
2184 si->data = xmalloc (4);
2185 si->size = 4;
2186
2187 if (exp->noname)
2188 {
2189 si->data[0] = exp->ordinal ;
2190 si->data[1] = exp->ordinal >> 8;
2191 si->data[2] = exp->ordinal >> 16;
2192 si->data[3] = 0x80;
2193 }
c027e8b0 2194 else
356c68ff
SC
2195 {
2196 sec->reloc_count = 1;
2197 memset (si->data, 0, si->size);
2198 rel = xmalloc (sizeof (arelent));
2199 rpp = xmalloc (sizeof (arelent *) * 2);
2200 rpp[0] = rel;
2201 rpp[1] = 0;
2202 rel->address = 0;
2203 rel->addend = 0;
2204 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2205 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2206 sec->orelocation = rpp;
2207 }
2208
2209 break;
2210
2211 case IDATA6:
c027e8b0 2212 if (!exp->noname)
356c68ff 2213 {
9d04d618
TT
2214 /* This used to add 1 to exp->hint. I don't know
2215 why it did that, and it does not match what I see
2216 in programs compiled with the MS tools. */
2217 int idx = exp->hint;
356c68ff
SC
2218 si->size = strlen (xlate (exp->name)) + 3;
2219 si->data = xmalloc (si->size);
2220 si->data[0] = idx & 0xff;
2221 si->data[1] = idx >> 8;
2222 strcpy (si->data + 2, xlate (exp->name));
2223 }
2224 break;
2225 case IDATA7:
2226 si->size = 4;
2227 si->data =xmalloc(4);
2228 memset (si->data, 0, si->size);
2229 rel = xmalloc (sizeof (arelent));
2230 rpp = xmalloc (sizeof (arelent *) * 2);
2231 rpp[0] = rel;
2232 rel->address = 0;
2233 rel->addend = 0;
a33f7359 2234 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
356c68ff
SC
2235 rel->sym_ptr_ptr = iname_lab_pp;
2236 sec->orelocation = rpp;
2237 sec->reloc_count = 1;
2238 break;
b10f8e5e 2239
a33f7359 2240#ifdef DLLTOOL_PPC
b10f8e5e
KK
2241 case PDATA:
2242 {
2243 /* The .pdata section is 5 words long. */
2244 /* Think of it as: */
2245 /* struct */
2246 /* { */
2247 /* bfd_vma BeginAddress, [0x00] */
2248 /* EndAddress, [0x04] */
2249 /* ExceptionHandler, [0x08] */
2250 /* HandlerData, [0x0c] */
2251 /* PrologEndAddress; [0x10] */
2252 /* }; */
2253
2254 /* So this pdata section setups up this as a glue linkage to
2255 a dll routine. There are a number of house keeping things
2256 we need to do:
2257
c027e8b0
ILT
2258 1. In the name of glue trickery, the ADDR32 relocs for 0,
2259 4, and 0x10 are set to point to the same place:
2260 "..function_name".
2261 2. There is one more reloc needed in the pdata section.
2262 The actual glue instruction to restore the toc on
b10f8e5e
KK
2263 return is saved as the offset in an IMGLUE reloc.
2264 So we need a total of four relocs for this section.
2265
2266 3. Lastly, the HandlerData field is set to 0x03, to indicate
2267 that this is a glue routine.
2268 */
2269 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
2270
2271 /* alignment must be set to 2**2 or you get extra stuff */
2272 bfd_set_section_alignment(abfd, sec, 2);
2273
2274 si->size = 4 * 5;
2275 si->data =xmalloc(4 * 5);
2276 memset (si->data, 0, si->size);
2277 rpp = xmalloc (sizeof (arelent *) * 5);
2278 rpp[0] = imglue = xmalloc (sizeof (arelent));
2279 rpp[1] = ba_rel = xmalloc (sizeof (arelent));
2280 rpp[2] = ea_rel = xmalloc (sizeof (arelent));
2281 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
2282 rpp[4] = 0;
2283
2284 /* stick the toc reload instruction in the glue reloc */
2285 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
2286
2287 imglue->addend = 0;
c027e8b0 2288 imglue->howto = bfd_reloc_type_lookup (abfd,
b10f8e5e
KK
2289 BFD_RELOC_32_GOTOFF);
2290 imglue->sym_ptr_ptr = fn_pp;
2291
2292 ba_rel->address = 0;
2293 ba_rel->addend = 0;
2294 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2295 ba_rel->sym_ptr_ptr = fn_pp;
2296
2297 bfd_put_32(abfd, 0x18, si->data + 0x04);
2298 ea_rel->address = 4;
2299 ea_rel->addend = 0;
2300 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2301 ea_rel->sym_ptr_ptr = fn_pp;
2302
2303 /* mark it as glue */
2304 bfd_put_32(abfd, 0x03, si->data + 0x0c);
2305
2306 /* mark the prolog end address */
2307 bfd_put_32(abfd, 0x0D, si->data + 0x10);
2308 pea_rel->address = 0x10;
2309 pea_rel->addend = 0;
2310 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2311 pea_rel->sym_ptr_ptr = fn_pp;
2312
2313 sec->orelocation = rpp;
2314 sec->reloc_count = 4;
2315 break;
2316 }
2317 case RDATA:
2318 /* Each external function in a PowerPC PE file has a two word
2319 descriptor consisting of:
2320 1. The address of the code.
2321 2. The address of the appropriate .toc
2322 We use relocs to build this.
2323 */
2324
2325 si->size = 8;
a33f7359 2326 si->data = xmalloc (8);
b10f8e5e
KK
2327 memset (si->data, 0, si->size);
2328
2329 rpp = xmalloc (sizeof (arelent *) * 3);
2330 rpp[0] = rel = xmalloc (sizeof (arelent));
2331 rpp[1] = xmalloc (sizeof (arelent));
2332 rpp[2] = 0;
2333
2334 rel->address = 0;
2335 rel->addend = 0;
2336 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2337 rel->sym_ptr_ptr = fn_pp;
2338
2339 rel = rpp[1];
2340
2341 rel->address = 4;
2342 rel->addend = 0;
2343 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2344 rel->sym_ptr_ptr = toc_pp;
2345
2346 sec->orelocation = rpp;
2347 sec->reloc_count = 2;
2348 break;
a33f7359 2349#endif /* DLLTOOL_PPC */
356c68ff
SC
2350 }
2351 }
2352
2353 {
2354 bfd_vma vma = 0;
2355 /* Size up all the sections */
2356 for (i = 0; i < NSECS; i++)
2357 {
2358 sinfo *si = secdata + i;
b10f8e5e 2359
356c68ff
SC
2360 bfd_set_section_size (abfd, si->sec, si->size);
2361 bfd_set_section_vma (abfd, si->sec, vma);
b10f8e5e 2362
356c68ff
SC
2363/* vma += si->size;*/
2364 }
2365 }
2366 /* Write them out */
2367 for (i = 0; i < NSECS; i++)
2368 {
2369 sinfo *si = secdata + i;
b10f8e5e 2370
356c68ff
SC
2371 if (i == IDATA5 && no_idata5)
2372 continue;
2373
2374 if (i == IDATA4 && no_idata4)
2375 continue;
2376
c027e8b0 2377 bfd_set_section_contents (abfd, si->sec,
356c68ff
SC
2378 si->data, 0,
2379 si->size);
2380 }
2381
2382 bfd_set_symtab (abfd, ptrs, oidx);
2383 bfd_close (abfd);
2384 abfd = bfd_openr (outname, HOW_BFD_TARGET);
2385 return abfd;
2386 }
061ed861 2387#endif
356c68ff
SC
2388}
2389
b10f8e5e 2390static bfd *
a33f7359 2391make_head ()
356c68ff 2392{
061ed861 2393 FILE * f = fopen (TMP_HEAD_S, FOPEN_WT);
356c68ff
SC
2394
2395 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2396 fprintf (f, "\t.section .idata$2\n");
2397
2398 fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
2399
2400 fprintf (f, "%s:\n", head_label);
2401
2402 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2403 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2404
2405 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2406 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2407 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2408 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2409 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2410 ASM_RVA_BEFORE,
2411 imp_name_lab,
2412 ASM_RVA_AFTER,
2413 ASM_C);
2414 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2415 ASM_RVA_BEFORE,
2416 ASM_RVA_AFTER, ASM_C);
2417
2418 fprintf (f, "%sStuff for compatibility\n", ASM_C);
2419
c027e8b0 2420 if (!no_idata5)
356c68ff
SC
2421 {
2422 fprintf (f, "\t.section\t.idata$5\n");
2423 fprintf (f, "\t%s\t0\n", ASM_LONG);
2424 fprintf (f, "fthunk:\n");
2425 }
c027e8b0 2426 if (!no_idata4)
356c68ff
SC
2427 {
2428 fprintf (f, "\t.section\t.idata$4\n");
2429
2430 fprintf (f, "\t%s\t0\n", ASM_LONG);
2431 fprintf (f, "\t.section .idata$4\n");
2432 fprintf (f, "hname:\n");
2433 }
2434 fclose (f);
2435
061ed861
NC
2436 sprintf (outfile, "%s -o %s %s", as_flags, TMP_HEAD_O, TMP_HEAD_S);
2437
2438#ifdef DLLTOOL_ARM
2439 if (interwork)
2440 strcat (outfile, " -mthumb-interwork");
2441#endif
2442
356c68ff
SC
2443 run (as_name, outfile);
2444
061ed861 2445 return bfd_openr (TMP_HEAD_O, HOW_BFD_TARGET);
356c68ff
SC
2446}
2447
c027e8b0 2448static bfd *
a33f7359 2449make_tail ()
356c68ff 2450{
061ed861 2451 FILE * f = fopen (TMP_TAIL_S, FOPEN_WT);
b10f8e5e 2452
c027e8b0 2453 if (!no_idata4)
356c68ff
SC
2454 {
2455 fprintf (f, "\t.section .idata$4\n");
2456 fprintf (f, "\t%s\t0\n", ASM_LONG);
2457 }
c027e8b0 2458 if (!no_idata5)
356c68ff
SC
2459 {
2460 fprintf (f, "\t.section .idata$5\n");
2461 fprintf (f, "\t%s\t0\n", ASM_LONG);
2462 }
b10f8e5e 2463
b10f8e5e
KK
2464#ifdef DLLTOOL_PPC
2465 /* Normally, we need to see a null descriptor built in idata$3 to
2466 act as the terminator for the list. The ideal way, I suppose,
2467 would be to mark this section as a comdat type 2 section, so
2468 only one would appear in the final .exe (if our linker supported
2469 comdat, that is) or cause it to be inserted by something else (say
2470 crt0)
2471 */
2472
2473 fprintf (f, "\t.section .idata$3\n");
2474 fprintf (f, "\t%s\t0\n", ASM_LONG);
2475 fprintf (f, "\t%s\t0\n", ASM_LONG);
2476 fprintf (f, "\t%s\t0\n", ASM_LONG);
2477 fprintf (f, "\t%s\t0\n", ASM_LONG);
2478 fprintf (f, "\t%s\t0\n", ASM_LONG);
2479#endif
2480
a33f7359
ILT
2481#ifdef DLLTOOL_PPC
2482 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2483 do too. Original, huh? */
2484 fprintf (f, "\t.section .idata$6\n");
2485#else
2486 fprintf (f, "\t.section .idata$7\n");
2487#endif
2488
2489 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
2490 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
2491 imp_name_lab, ASM_TEXT, dll_name);
2492
2757dc25
SC
2493 fclose (f);
2494
061ed861
NC
2495 sprintf (outfile, "%s -o %s %s", as_flags, TMP_TAIL_O, TMP_TAIL_S);
2496
2497#ifdef DLLTOOL_ARM
2498 if (interwork)
2499 strcat (outfile, " -mthumb-interwork");
2500#endif
2501
2757dc25 2502 run (as_name, outfile);
061ed861
NC
2503
2504 return bfd_openr (TMP_TAIL_O, HOW_BFD_TARGET);
356c68ff 2505}
2757dc25 2506
356c68ff
SC
2507static void
2508gen_lib_file ()
2509{
2510 int i;
2511 export_type *exp;
2512 bfd *ar_head;
2513 bfd *ar_tail;
2514 bfd *outarch;
2515 bfd * head = 0;
2757dc25 2516
356c68ff 2517 unlink (imp_name);
2757dc25 2518
356c68ff 2519 outarch = bfd_openw (imp_name, HOW_BFD_TARGET);
2757dc25 2520
356c68ff 2521 if (!outarch)
061ed861
NC
2522 /* xgettext:c-format */
2523 fatal (_("Can't open .lib file: %s"), imp_name);
2524
2525 /* xgettext:c-format */
2526 inform (_("Creating library file: %s\n"), imp_name);
2527
356c68ff
SC
2528 bfd_set_format (outarch, bfd_archive);
2529 outarch->has_armap = 1;
2530
2531 /* Work out a reasonable size of things to put onto one line. */
2757dc25 2532
356c68ff
SC
2533 ar_head = make_head ();
2534 ar_tail = make_tail();
2535
061ed861
NC
2536 if (ar_head == NULL || ar_tail == NULL)
2537 return;
2538
356c68ff
SC
2539 for (i = 0; (exp = d_exports_lexically[i]); i++)
2540 {
2541 bfd *n = make_one_lib_file (exp, i);
2542 n->next = head;
2543 head = n;
765e60a9 2544 }
356c68ff 2545
356c68ff
SC
2546 /* Now stick them all into the archive */
2547
2548 ar_head->next = head;
2549 ar_tail->next = ar_head;
2550 head = ar_tail;
2551
c336631b
ILT
2552 if (! bfd_set_archive_head (outarch, head))
2553 bfd_fatal ("bfd_set_archive_head");
061ed861 2554
c336631b
ILT
2555 if (! bfd_close (outarch))
2556 bfd_fatal (imp_name);
2557
2558 while (head != NULL)
2559 {
2560 bfd *n = head->next;
2561 bfd_close (head);
2562 head = n;
2563 }
765e60a9 2564
2757dc25 2565 /* Delete all the temp files */
765e60a9 2566
f88ebc68 2567 if (dontdeltemps == 0)
2757dc25 2568 {
061ed861
NC
2569 unlink (TMP_HEAD_O);
2570 unlink (TMP_HEAD_S);
2571 unlink (TMP_TAIL_O);
2572 unlink (TMP_TAIL_S);
2757dc25 2573 }
f88ebc68 2574
199f5217 2575 if (dontdeltemps < 2)
9d04d618
TT
2576 {
2577 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2578 {
061ed861 2579 sprintf (outfile, "%s%d.o", TMP_STUB, i);
9d04d618 2580 if (unlink (outfile) < 0)
061ed861
NC
2581 /* xgettext:c-format */
2582 warn (_("cannot delete %s: %s\n"), outfile, strerror (errno));
9d04d618
TT
2583 }
2584 }
061ed861
NC
2585
2586 inform (_("Created lib file"));
765e60a9 2587}
9d04d618 2588
765e60a9
SC
2589/**********************************************************************/
2590
2591/* Run through the information gathered from the .o files and the
2592 .def file and work out the best stuff */
a33f7359 2593static int
765e60a9 2594pfunc (a, b)
a33f7359
ILT
2595 const void *a;
2596 const void *b;
765e60a9
SC
2597{
2598 export_type *ap = *(export_type **) a;
2599 export_type *bp = *(export_type **) b;
2600 if (ap->ordinal == bp->ordinal)
2601 return 0;
2602
2603 /* unset ordinals go to the bottom */
2604 if (ap->ordinal == -1)
2605 return 1;
2606 if (bp->ordinal == -1)
2607 return -1;
2608 return (ap->ordinal - bp->ordinal);
2609}
2610
a33f7359 2611static int
765e60a9 2612nfunc (a, b)
a33f7359
ILT
2613 const void *a;
2614 const void *b;
765e60a9
SC
2615{
2616 export_type *ap = *(export_type **) a;
2617 export_type *bp = *(export_type **) b;
2618
2619 return (strcmp (ap->name, bp->name));
2620}
2621
a33f7359 2622static void
765e60a9
SC
2623remove_null_names (ptr)
2624 export_type **ptr;
2625{
2626 int src;
2627 int dst;
2628 for (dst = src = 0; src < d_nfuncs; src++)
2629 {
2630 if (ptr[src])
2631 {
2632 ptr[dst] = ptr[src];
2633 dst++;
2634 }
2635 }
2636 d_nfuncs = dst;
2637}
2638
2639static void
2640dtab (ptr)
2641 export_type **ptr;
2642{
2643#ifdef SACDEBUG
2644 int i;
2645 for (i = 0; i < d_nfuncs; i++)
2646 {
2647 if (ptr[i])
2648 {
c336631b 2649 printf ("%d %s @ %d %s%s%s\n",
765e60a9
SC
2650 i, ptr[i]->name, ptr[i]->ordinal,
2651 ptr[i]->noname ? "NONAME " : "",
c336631b
ILT
2652 ptr[i]->constant ? "CONSTANT" : "",
2653 ptr[i]->data ? "DATA" : "");
765e60a9
SC
2654 }
2655 else
2656 printf ("empty\n");
2657 }
2658#endif
2659}
2660
2661static void
2662process_duplicates (d_export_vec)
2663 export_type **d_export_vec;
2664{
2665 int more = 1;
c027e8b0 2666 int i;
765e60a9
SC
2667 while (more)
2668 {
f051e1b0 2669
765e60a9
SC
2670 more = 0;
2671 /* Remove duplicates */
2672 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
2673
2674 dtab (d_export_vec);
2675 for (i = 0; i < d_nfuncs - 1; i++)
2676 {
2677 if (strcmp (d_export_vec[i]->name,
2678 d_export_vec[i + 1]->name) == 0)
2679 {
2680
2681 export_type *a = d_export_vec[i];
2682 export_type *b = d_export_vec[i + 1];
2683
2684 more = 1;
061ed861
NC
2685
2686 /* xgettext:c-format */
2687 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2688 a->name, a->ordinal, b->ordinal);
2689
765e60a9
SC
2690 if (a->ordinal != -1
2691 && b->ordinal != -1)
061ed861
NC
2692 /* xgettext:c-format */
2693 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2694 a->name);
765e60a9 2695
765e60a9
SC
2696 /* Merge attributes */
2697 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
2698 b->constant |= a->constant;
2699 b->noname |= a->noname;
c336631b 2700 b->data |= a->data;
765e60a9
SC
2701 d_export_vec[i] = 0;
2702 }
2703
2704 dtab (d_export_vec);
2705 remove_null_names (d_export_vec);
2706 dtab (d_export_vec);
2707 }
2708 }
f051e1b0
SC
2709
2710
2711 /* Count the names */
2712 for (i = 0; i < d_nfuncs; i++)
2713 {
2714 if (!d_export_vec[i]->noname)
2715 d_named_nfuncs++;
2716 }
765e60a9
SC
2717}
2718
2719static void
2720fill_ordinals (d_export_vec)
2721 export_type **d_export_vec;
2722{
a33f7359 2723 int lowest = -1;
f051e1b0 2724 int i;
6f2d3212 2725 char *ptr;
a33f7359
ILT
2726 int size = 65536;
2727
765e60a9
SC
2728 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2729
6f2d3212
SC
2730 /* fill in the unset ordinals with ones from our range */
2731
a33f7359 2732 ptr = (char *) xmalloc (size);
6f2d3212 2733
a33f7359 2734 memset (ptr, 0, size);
6f2d3212
SC
2735
2736 /* Mark in our large vector all the numbers that are taken */
765e60a9
SC
2737 for (i = 0; i < d_nfuncs; i++)
2738 {
6f2d3212 2739 if (d_export_vec[i]->ordinal != -1)
765e60a9 2740 {
6f2d3212 2741 ptr[d_export_vec[i]->ordinal] = 1;
a33f7359
ILT
2742 if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
2743 {
2744 lowest = d_export_vec[i]->ordinal;
2745 }
765e60a9 2746 }
6f2d3212
SC
2747 }
2748
20dec772 2749 /* Start at 1 for compatibility with MS toolchain. */
a33f7359 2750 if (lowest == -1)
20dec772
ILT
2751 lowest = 1;
2752
a33f7359 2753 /* Now fill in ordinals where the user wants us to choose. */
6f2d3212
SC
2754 for (i = 0; i < d_nfuncs; i++)
2755 {
2756 if (d_export_vec[i]->ordinal == -1)
765e60a9 2757 {
a33f7359
ILT
2758 register int j;
2759
2760 /* First try within or after any user supplied range. */
2761 for (j = lowest; j < size; j++)
6f2d3212
SC
2762 if (ptr[j] == 0)
2763 {
2764 ptr[j] = 1;
2765 d_export_vec[i]->ordinal = j;
2766 goto done;
2767 }
2768
a33f7359
ILT
2769 /* Then try before the range. */
2770 for (j = lowest; j >0; j--)
6f2d3212
SC
2771 if (ptr[j] == 0)
2772 {
2773 ptr[j] = 1;
2774 d_export_vec[i]->ordinal = j;
2775 goto done;
2776 }
2777 done:;
765e60a9
SC
2778 }
2779 }
2780
6f2d3212
SC
2781 free (ptr);
2782
2783 /* And resort */
2784
2785 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2786
799de4c4 2787 /* Work out the lowest and highest ordinal numbers. */
c027e8b0 2788 if (d_nfuncs)
356c68ff 2789 {
799de4c4
DE
2790 if (d_export_vec[0])
2791 d_low_ord = d_export_vec[0]->ordinal;
356c68ff
SC
2792 if (d_export_vec[d_nfuncs-1])
2793 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
2794 }
f051e1b0
SC
2795}
2796
a33f7359
ILT
2797static int
2798alphafunc (av,bv)
2799 const void *av;
2800 const void *bv;
f051e1b0 2801{
a33f7359
ILT
2802 const export_type **a = (const export_type **) av;
2803 const export_type **b = (const export_type **) bv;
f051e1b0
SC
2804
2805 return strcmp ((*a)->name, (*b)->name);
765e60a9 2806}
f051e1b0 2807
a33f7359 2808static void
765e60a9
SC
2809mangle_defs ()
2810{
2811 /* First work out the minimum ordinal chosen */
2812
2813 export_type *exp;
356c68ff 2814
765e60a9 2815 int i;
f051e1b0 2816 int hint = 0;
765e60a9
SC
2817 export_type **d_export_vec
2818 = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
2819
061ed861
NC
2820 inform (_("Processing definitions"));
2821
765e60a9
SC
2822 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2823 {
2824 d_export_vec[i] = exp;
2825 }
2826
2827 process_duplicates (d_export_vec);
2828 fill_ordinals (d_export_vec);
2829
2830 /* Put back the list in the new order */
2831 d_exports = 0;
2832 for (i = d_nfuncs - 1; i >= 0; i--)
2833 {
2834 d_export_vec[i]->next = d_exports;
2835 d_exports = d_export_vec[i];
2836 }
f051e1b0
SC
2837
2838 /* Build list in alpha order */
061ed861
NC
2839 d_exports_lexically = (export_type **)
2840 xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
f051e1b0
SC
2841
2842 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2843 {
2844 d_exports_lexically[i] = exp;
2845 }
2846 d_exports_lexically[i] = 0;
2847
2848 qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
2849
2850 /* Fill exp entries with their hint values */
c027e8b0 2851
f051e1b0
SC
2852 for (i = 0; i < d_nfuncs; i++)
2853 {
2854 if (!d_exports_lexically[i]->noname || show_allnames)
2855 d_exports_lexically[i]->hint = hint++;
2856 }
061ed861
NC
2857
2858 inform (_("Processed definitions"));
765e60a9
SC
2859}
2860
765e60a9
SC
2861/**********************************************************************/
2862
a33f7359 2863static void
faad4b47
ILT
2864usage (file, status)
2865 FILE *file;
765e60a9
SC
2866 int status;
2867{
061ed861 2868 /* xgetext:c-format */
faad4b47 2869 fprintf (file, _("Usage %s <options> <object-files>\n"), program_name);
061ed861 2870 /* xgetext:c-format */
faad4b47
ILT
2871 fprintf (file, _(" -m --machine <machine> Create {arm, i386, ppc, thumb} DLL. [default: %s]\n"), mname);
2872 fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n"));
2873 fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
2874 fprintf (file, _(" -a --add-indirect Add dll indirects to export file.\n"));
2875 fprintf (file, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
2876 fprintf (file, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
2877 fprintf (file, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
2878 fprintf (file, _(" --export-all-symbols Export all symbols to .def\n"));
2879 fprintf (file, _(" --no-export-all-symbols Only export listed symbols\n"));
2880 fprintf (file, _(" --exclude-symbols <list> Don't export <list>\n"));
2881 fprintf (file, _(" --no-default-excludes Clear default exclude symbols\n"));
2882 fprintf (file, _(" -b --base-file <basefile> Read linker generated base file.\n"));
2883 fprintf (file, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
2884 fprintf (file, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
2885 fprintf (file, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
2886 fprintf (file, _(" -k --kill-at Kill @<n> from exported names.\n"));
2887 fprintf (file, _(" -S --as <name> Use <name> for assembler.\n"));
2888 fprintf (file, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
061ed861 2889#ifdef DLLTOOL_ARM
faad4b47 2890 fprintf (file, _(" -i --interwork Support ARM/Thumb interworking.\n"));
061ed861 2891#endif
faad4b47
ILT
2892 fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
2893 fprintf (file, _(" -v --verbose Be verbose.\n"));
2894 fprintf (file, _(" -V --version Display the program version.\n"));
2895 fprintf (file, _(" -h --help Display this information.\n"));
061ed861 2896
765e60a9
SC
2897 exit (status);
2898}
2899
faad4b47
ILT
2900#define OPTION_EXPORT_ALL_SYMS 150
2901#define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
2902#define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
2903#define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
2904#define OPTION_NO_IDATA4 'x'
2905#define OPTION_NO_IDATA5 'c'
2906
a33f7359 2907static const struct option long_options[] =
765e60a9 2908{
061ed861 2909 {"no-delete", no_argument, NULL, 'n'},
531f86b4 2910 {"dllname", required_argument, NULL, 'D'},
356c68ff
SC
2911 {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
2912 {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
2757dc25 2913 {"output-exp", required_argument, NULL, 'e'},
531f86b4 2914 {"output-def", required_argument, NULL, 'z'},
faad4b47
ILT
2915 {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
2916 {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
2917 {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
2918 {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
2757dc25 2919 {"output-lib", required_argument, NULL, 'l'},
061ed861
NC
2920 {"def", required_argument, NULL, 'd'}, /* for compatiblity with older versions */
2921 {"input-def", required_argument, NULL, 'd'},
531f86b4 2922 {"add-underscore", no_argument, NULL, 'U'},
061ed861
NC
2923 {"kill-at", no_argument, NULL, 'k'},
2924 {"verbose", no_argument, NULL, 'v'},
2925 {"version", no_argument, NULL, 'V'},
765e60a9
SC
2926 {"help", no_argument, NULL, 'h'},
2927 {"machine", required_argument, NULL, 'm'},
199f5217 2928 {"add-indirect", no_argument, NULL, 'a'},
6f2d3212 2929 {"base-file", required_argument, NULL, 'b'},
356c68ff 2930 {"as", required_argument, NULL, 'S'},
061ed861
NC
2931 {"as-flags", required_argument, NULL, 'f'},
2932#ifdef DLLTOOL_ARM
2933 {"interwork", no_argument, NULL, 'i'},
2934#endif
356c68ff 2935 {0}
765e60a9
SC
2936};
2937
2938int
2939main (ac, av)
2940 int ac;
2941 char **av;
2942{
2943 int c;
f051e1b0 2944 int i;
765e60a9
SC
2945 char *firstarg = 0;
2946 program_name = av[0];
2947 oav = av;
6f2d3212 2948
061ed861 2949#ifdef HAVE_SETLOCALE
19ac4b08 2950 setlocale (LC_MESSAGES, "");
061ed861 2951#endif
19ac4b08
TT
2952 bindtextdomain (PACKAGE, LOCALEDIR);
2953 textdomain (PACKAGE);
2954
061ed861
NC
2955 while ((c = getopt_long (ac, av, "xcz:S:aD:l:e:nkvVb:Uh?m:d:f:i",
2956 long_options, 0))
356c68ff 2957 != EOF)
765e60a9
SC
2958 {
2959 switch (c)
2960 {
356c68ff
SC
2961 case OPTION_NO_IDATA4:
2962 no_idata4 = 1;
2963 break;
2964 case OPTION_NO_IDATA5:
2965 no_idata5 = 1;
2966 break;
faad4b47
ILT
2967 case OPTION_EXPORT_ALL_SYMS:
2968 export_all_symbols = true;
2969 break;
2970 case OPTION_NO_EXPORT_ALL_SYMS:
2971 export_all_symbols = false;
2972 break;
2973 case OPTION_EXCLUDE_SYMS:
2974 add_excludes (optarg);
2975 break;
2976 case OPTION_NO_DEFAULT_EXCLUDES:
2977 do_default_excludes = false;
2978 break;
356c68ff
SC
2979 case 'S':
2980 as_name = optarg;
2981 break;
061ed861
NC
2982 case 'f':
2983 as_flags = optarg;
2984 break;
356c68ff 2985
531f86b4
SC
2986 /* ignored for compatibility */
2987 case 'u':
2988 break;
199f5217
DE
2989 case 'a':
2990 add_indirect = 1;
2991 break;
531f86b4 2992 case 'z':
20dec772 2993 output_def = fopen (optarg, FOPEN_WT);
531f86b4 2994 break;
2757dc25
SC
2995 case 'D':
2996 dll_name = optarg;
2997 break;
2998 case 'l':
2999 imp_name = optarg;
3000 break;
3001 case 'e':
3002 exp_name = optarg;
3003 break;
765e60a9 3004 case 'h':
faad4b47 3005 usage (stdout, 0);
765e60a9
SC
3006 break;
3007 case 'm':
3008 mname = optarg;
3009 break;
6f2d3212
SC
3010 case 'v':
3011 verbose = 1;
3012 break;
061ed861
NC
3013 case 'V':
3014 print_version (program_name);
3015 break;
3016#ifdef DLLTOOL_ARM
3017 case 'i':
3018 interwork = 1;
3019 break;
3020#endif
2757dc25 3021 case 'y':
a33f7359
ILT
3022#if 0
3023 /* We don't currently define YYDEBUG when building
3024 defparse.y. */
765e60a9 3025 yydebug = 1;
a33f7359 3026#endif
765e60a9 3027 break;
531f86b4
SC
3028 case 'U':
3029 add_underscore = 1;
6f2d3212 3030 break;
00289839
SC
3031 case 'k':
3032 killat = 1;
3033 break;
765e60a9
SC
3034 case 'd':
3035 def_file = optarg;
3036 break;
2757dc25 3037 case 'n':
f88ebc68 3038 dontdeltemps++;
2757dc25 3039 break;
6f2d3212 3040 case 'b':
20dec772 3041 base_file = fopen (optarg, FOPEN_RB);
061ed861 3042
6f2d3212 3043 if (!base_file)
061ed861
NC
3044 /* xgettext:c-format */
3045 fatal (_("Unable to open base-file: %s"), optarg);
3046
6f2d3212 3047 break;
765e60a9 3048 default:
faad4b47
ILT
3049 usage (stderr, 1);
3050 break;
765e60a9
SC
3051 }
3052 }
3053
6f2d3212 3054 for (i = 0; mtable[i].type; i++)
765e60a9
SC
3055 {
3056 if (strcmp (mtable[i].type, mname) == 0)
3057 break;
3058 }
3059
6f2d3212 3060 if (!mtable[i].type)
061ed861
NC
3061 /* xgettext:c-format */
3062 fatal (_("Machine '%s' not supported"), mname);
765e60a9 3063
061ed861 3064 machine = i;
765e60a9 3065
061ed861
NC
3066#ifdef DLLTOOL_ARM
3067 /* Always enable interworking for Thumb targets. */
3068 if (machine == MTHUMB && (! interwork))
3069 interwork = 1;
3070#endif
3071
2757dc25
SC
3072 if (!dll_name && exp_name)
3073 {
a4e5fd18 3074 int len = strlen (exp_name) + 5;
2757dc25
SC
3075 dll_name = xmalloc (len);
3076 strcpy (dll_name, exp_name);
3077 strcat (dll_name, ".dll");
3078 }
2757dc25 3079
faad4b47
ILT
3080 /* Don't use the default exclude list if we're reading only the
3081 symbols in the .drectve section. The default excludes are meant
3082 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3083 if (! export_all_symbols)
3084 do_default_excludes = false;
3085
3086 if (do_default_excludes)
3087 set_default_excludes ();
3088
765e60a9 3089 if (def_file)
061ed861
NC
3090 process_def_file (def_file);
3091
765e60a9
SC
3092 while (optind < ac)
3093 {
3094 if (!firstarg)
3095 firstarg = av[optind];
3096 scan_obj_file (av[optind]);
3097 optind++;
3098 }
3099
765e60a9 3100 mangle_defs ();
6f2d3212 3101
2757dc25
SC
3102 if (exp_name)
3103 gen_exp_file ();
061ed861 3104
2757dc25 3105 if (imp_name)
531f86b4
SC
3106 {
3107 /* Make imp_name safe for use as a label. */
3108 char *p;
a33f7359
ILT
3109
3110 imp_name_lab = xstrdup (imp_name);
3111 for (p = imp_name_lab; *p; p++)
531f86b4 3112 {
c027e8b0 3113 if (!isalpha ((unsigned char) *p) && !isdigit ((unsigned char) *p))
531f86b4
SC
3114 *p = '_';
3115 }
356c68ff 3116 head_label = make_label("_head_", imp_name_lab);
531f86b4
SC
3117 gen_lib_file ();
3118 }
061ed861 3119
531f86b4
SC
3120 if (output_def)
3121 gen_def_file ();
6f2d3212 3122
765e60a9
SC
3123 return 0;
3124}
This page took 0.264514 seconds and 4 git commands to generate.