OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [binutils/] [dlltool.c] - Blame information for rev 855

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.