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