]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/pe-dll.c
gas/
[thirdparty/binutils-gdb.git] / ld / pe-dll.c
CommitLineData
252b5132 1/* Routines to help build PEI-format DLLs (Win32 etc)
47639182 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
4d8907ac 3 Free Software Foundation, Inc.
252b5132
RH
4 Written by DJ Delorie <dj@cygnus.com>
5
6 This file is part of GLD, the Gnu Linker.
7
8 GLD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GLD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GLD; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
22
23#include "bfd.h"
24#include "sysdep.h"
25#include "bfdlink.h"
26#include "libiberty.h"
3882b010 27#include "safe-ctype.h"
252b5132
RH
28
29#include <time.h>
252b5132
RH
30
31#include "ld.h"
32#include "ldexp.h"
33#include "ldlang.h"
34#include "ldwrite.h"
35#include "ldmisc.h"
df2a7313 36#include <ldgram.h>
252b5132 37#include "ldmain.h"
b71e2778 38#include "ldfile.h"
252b5132
RH
39#include "ldemul.h"
40#include "coff/internal.h"
41#include "../bfd/libcoff.h"
42#include "deffile.h"
1069dd8d 43#include "pe-dll.h"
252b5132 44
775cabad
NC
45/* This file turns a regular Windows PE image into a DLL. Because of
46 the complexity of this operation, it has been broken down into a
47 number of separate modules which are all called by the main function
48 at the end of this file. This function is not re-entrant and is
49 normally only called once, so static variables are used to reduce
50 the number of parameters and return values required.
b7a26f91 51
775cabad
NC
52 See also: ld/emultempl/pe.em. */
53
54/* Auto-import feature by Paul Sokolovsky
55
56 Quick facts:
57
58 1. With this feature on, DLL clients can import variables from DLL
59 without any concern from their side (for example, without any source
60 code modifications).
61
62 2. This is done completely in bounds of the PE specification (to be fair,
396a2467 63 there's a place where it pokes nose out of, but in practice it works).
775cabad
NC
64 So, resulting module can be used with any other PE compiler/linker.
65
66 3. Auto-import is fully compatible with standard import method and they
67 can be mixed together.
68
69 4. Overheads: space: 8 bytes per imported symbol, plus 20 for each
70 reference to it; load time: negligible; virtual/physical memory: should be
71 less than effect of DLL relocation, and I sincerely hope it doesn't affect
72 DLL sharability (too much).
73
74 Idea
75
76 The obvious and only way to get rid of dllimport insanity is to make client
77 access variable directly in the DLL, bypassing extra dereference. I.e.,
396a2467 78 whenever client contains something like
775cabad
NC
79
80 mov dll_var,%eax,
81
82 address of dll_var in the command should be relocated to point into loaded
83 DLL. The aim is to make OS loader do so, and than make ld help with that.
84 Import section of PE made following way: there's a vector of structures
85 each describing imports from particular DLL. Each such structure points
396a2467 86 to two other parallel vectors: one holding imported names, and one which
775cabad
NC
87 will hold address of corresponding imported name. So, the solution is
88 de-vectorize these structures, making import locations be sparse and
89 pointing directly into code. Before continuing, it is worth a note that,
90 while authors strives to make PE act ELF-like, there're some other people
91 make ELF act PE-like: elfvector, ;-) .
92
93 Implementation
94
95 For each reference of data symbol to be imported from DLL (to set of which
96 belong symbols with name <sym>, if __imp_<sym> is found in implib), the
97 import fixup entry is generated. That entry is of type
98 IMAGE_IMPORT_DESCRIPTOR and stored in .idata$3 subsection. Each
99 fixup entry contains pointer to symbol's address within .text section
100 (marked with __fuN_<sym> symbol, where N is integer), pointer to DLL name
101 (so, DLL name is referenced by multiple entries), and pointer to symbol
102 name thunk. Symbol name thunk is singleton vector (__nm_th_<symbol>)
103 pointing to IMAGE_IMPORT_BY_NAME structure (__nm_<symbol>) directly
104 containing imported name. Here comes that "om the edge" problem mentioned
105 above: PE specification rambles that name vector (OriginalFirstThunk)
106 should run in parallel with addresses vector (FirstThunk), i.e. that they
107 should have same number of elements and terminated with zero. We violate
396a2467 108 this, since FirstThunk points directly into machine code. But in practice,
775cabad
NC
109 OS loader implemented the sane way: it goes thru OriginalFirstThunk and
110 puts addresses to FirstThunk, not something else. It once again should be
111 noted that dll and symbol name structures are reused across fixup entries
112 and should be there anyway to support standard import stuff, so sustained
113 overhead is 20 bytes per reference. Other question is whether having several
114 IMAGE_IMPORT_DESCRIPTORS for the same DLL is possible. Answer is yes, it is
115 done even by native compiler/linker (libth32's functions are in fact reside
116 in windows9x kernel32.dll, so if you use it, you have two
117 IMAGE_IMPORT_DESCRIPTORS for kernel32.dll). Yet other question is whether
118 referencing the same PE structures several times is valid. The answer is why
396a2467 119 not, prohibiting that (detecting violation) would require more work on
775cabad
NC
120 behalf of loader than not doing it.
121
122 See also: ld/emultempl/pe.em. */
b044cda1 123
1579bae1 124static void add_bfd_to_link (bfd *, const char *, struct bfd_link_info *);
b044cda1 125
775cabad 126/* For emultempl/pe.em. */
252b5132 127
775cabad 128def_file * pe_def_file = 0;
252b5132
RH
129int pe_dll_export_everything = 0;
130int pe_dll_do_default_excludes = 1;
131int pe_dll_kill_ats = 0;
132int pe_dll_stdcall_aliases = 0;
870df5dc
NC
133int pe_dll_warn_dup_exports = 0;
134int pe_dll_compat_implib = 0;
b044cda1 135int pe_dll_extra_pe_debug = 0;
252b5132 136
775cabad 137/* Static variables and types. */
252b5132
RH
138
139static bfd_vma image_base;
252b5132 140static bfd *filler_bfd;
198beae2 141static struct bfd_section *edata_s, *reloc_s;
252b5132 142static unsigned char *edata_d, *reloc_d;
1069dd8d 143static size_t edata_sz, reloc_sz;
2fa9fc65 144static int runtime_pseudo_relocs_created = 0;
252b5132 145
775cabad
NC
146typedef struct
147 {
148 char *target_name;
149 char *object_target;
150 unsigned int imagebase_reloc;
151 int pe_arch;
152 int bfd_arch;
153 int underscored;
154 }
155pe_details_type;
156
157typedef struct
158 {
159 char *name;
160 int len;
161 }
162autofilter_entry_type;
b044cda1 163
c6c37250 164#define PE_ARCH_i386 1
344a211f
NC
165#define PE_ARCH_sh 2
166#define PE_ARCH_mips 3
167#define PE_ARCH_arm 4
775cabad 168#define PE_ARCH_arm_epoc 5
c6c37250 169
775cabad
NC
170static pe_details_type pe_detail_list[] =
171{
c6c37250
DD
172 {
173 "pei-i386",
174 "pe-i386",
175 7 /* R_IMAGEBASE */,
176 PE_ARCH_i386,
177 bfd_arch_i386,
178 1
179 },
344a211f
NC
180 {
181 "pei-shl",
182 "pe-shl",
183 16 /* R_SH_IMAGEBASE */,
184 PE_ARCH_sh,
185 bfd_arch_sh,
186 1
187 },
188 {
189 "pei-mips",
190 "pe-mips",
191 34 /* MIPS_R_RVA */,
192 PE_ARCH_mips,
193 bfd_arch_mips,
194 0
195 },
196 {
197 "pei-arm-little",
198 "pe-arm-little",
199 11 /* ARM_RVA32 */,
200 PE_ARCH_arm,
201 bfd_arch_arm,
2b817be1 202 1
344a211f 203 },
775cabad
NC
204 {
205 "epoc-pei-arm-little",
206 "epoc-pe-arm-little",
207 11 /* ARM_RVA32 */,
208 PE_ARCH_arm_epoc,
209 bfd_arch_arm,
210 0
211 },
1069dd8d 212 { NULL, NULL, 0, 0, 0, 0 }
c6c37250
DD
213};
214
215static pe_details_type *pe_details;
216
775cabad
NC
217static autofilter_entry_type autofilter_symbollist[] =
218{
b044cda1
CW
219 { "DllMain@12", 10 },
220 { "DllEntryPoint@0", 15 },
221 { "DllMainCRTStartup@12", 20 },
222 { "_cygwin_dll_entry@12", 20 },
223 { "_cygwin_crt0_common@8", 21 },
224 { "_cygwin_noncygwin_dll_entry@12", 30 },
225 { "impure_ptr", 10 },
1c43e6e5
NC
226 { "_pei386_runtime_relocator", 25 },
227 { "do_pseudo_reloc", 15 },
54d4efe3 228 { "cygwin_crt0", 11 },
b044cda1
CW
229 { NULL, 0 }
230};
775cabad
NC
231
232/* Do not specify library suffix explicitly, to allow for dllized versions. */
233static autofilter_entry_type autofilter_liblist[] =
234{
602d6c6f 235 { "libcygwin", 9 },
75c2ea5b
CF
236 { "libgcc", 6 },
237 { "libstdc++", 9 },
238 { "libmingw32", 10 },
9e8d33e7 239 { "libmingwex", 10 },
75c2ea5b
CF
240 { "libg2c", 6 },
241 { "libsupc++", 9 },
242 { "libobjc", 7 },
9e8d33e7 243 { "libgcj", 6 },
b044cda1
CW
244 { NULL, 0 }
245};
775cabad
NC
246
247static autofilter_entry_type autofilter_objlist[] =
248{
b044cda1
CW
249 { "crt0.o", 6 },
250 { "crt1.o", 6 },
251 { "crt2.o", 6 },
5b784096
DD
252 { "dllcrt1.o", 9 },
253 { "dllcrt2.o", 9 },
59d28a94 254 { "gcrt0.o", 7 },
663dd378 255 { "gcrt1.o", 7 },
b7a26f91 256 { "gcrt2.o", 7 },
70b0be79
CF
257 { "crtbegin.o", 10 },
258 { "crtend.o", 8 },
b044cda1
CW
259 { NULL, 0 }
260};
775cabad
NC
261
262static autofilter_entry_type autofilter_symbolprefixlist[] =
263{
264 /* { "__imp_", 6 }, */
265 /* Do __imp_ explicitly to save time. */
b044cda1 266 { "__rtti_", 7 },
39cebe23
NC
267 /* Don't re-export auto-imported symbols. */
268 { "_nm_", 4 },
b044cda1 269 { "__builtin_", 10 },
775cabad
NC
270 /* Don't export symbols specifying internal DLL layout. */
271 { "_head_", 6 },
b044cda1
CW
272 { "_fmode", 6 },
273 { "_impure_ptr", 11 },
274 { "cygwin_attach_dll", 17 },
275 { "cygwin_premain0", 15 },
276 { "cygwin_premain1", 15 },
277 { "cygwin_premain2", 15 },
278 { "cygwin_premain3", 15 },
279 { "environ", 7 },
280 { NULL, 0 }
281};
775cabad
NC
282
283static autofilter_entry_type autofilter_symbolsuffixlist[] =
284{
b044cda1
CW
285 { "_iname", 6 },
286 { NULL, 0 }
287};
288
c6c37250
DD
289#define U(str) (pe_details->underscored ? "_" str : str)
290
291void
1579bae1 292pe_dll_id_target (const char *target)
c6c37250
DD
293{
294 int i;
775cabad 295
d643799d 296 for (i = 0; pe_detail_list[i].target_name; i++)
9d68bc82
DD
297 if (strcmp (pe_detail_list[i].target_name, target) == 0
298 || strcmp (pe_detail_list[i].object_target, target) == 0)
c6c37250 299 {
d643799d 300 pe_details = pe_detail_list + i;
c6c37250
DD
301 return;
302 }
303 einfo (_("%XUnsupported PEI architecture: %s\n"), target);
304 exit (1);
305}
306
b7a26f91 307/* Helper functions for qsort. Relocs must be sorted so that we can write
775cabad 308 them out by pages. */
252b5132 309
775cabad
NC
310typedef struct
311 {
312 bfd_vma vma;
313 char type;
314 short extra;
315 }
316reloc_data_type;
c6c37250 317
252b5132 318static int
1579bae1 319reloc_sort (const void *va, const void *vb)
252b5132 320{
1579bae1
AM
321 bfd_vma a = ((const reloc_data_type *) va)->vma;
322 bfd_vma b = ((const reloc_data_type *) vb)->vma;
775cabad 323
c6c37250 324 return (a > b) ? 1 : ((a < b) ? -1 : 0);
252b5132
RH
325}
326
327static int
1579bae1 328pe_export_sort (const void *va, const void *vb)
252b5132 329{
1579bae1
AM
330 const def_file_export *a = va;
331 const def_file_export *b = vb;
775cabad 332
252b5132
RH
333 return strcmp (a->name, b->name);
334}
335
775cabad 336/* Read and process the .DEF file. */
252b5132
RH
337
338/* These correspond to the entries in pe_def_file->exports[]. I use
339 exported_symbol_sections[i] to tag whether or not the symbol was
5cc18311 340 defined, since we can't export symbols we don't have. */
252b5132
RH
341
342static bfd_vma *exported_symbol_offsets;
198beae2 343static struct bfd_section **exported_symbol_sections;
252b5132
RH
344static int export_table_size;
345static int count_exported;
346static int count_exported_byname;
347static int count_with_ordinals;
348static const char *dll_name;
349static int min_ordinal, max_ordinal;
350static int *exported_symbols;
351
775cabad
NC
352typedef struct exclude_list_struct
353 {
354 char *string;
355 struct exclude_list_struct *next;
658957db 356 int type;
775cabad
NC
357 }
358exclude_list_struct;
86b1cc60 359
252b5132
RH
360static struct exclude_list_struct *excludes = 0;
361
362void
1579bae1 363pe_dll_add_excludes (const char *new_excludes, const int type)
252b5132
RH
364{
365 char *local_copy;
366 char *exclude_string;
367
368 local_copy = xstrdup (new_excludes);
369
370 exclude_string = strtok (local_copy, ",:");
371 for (; exclude_string; exclude_string = strtok (NULL, ",:"))
372 {
373 struct exclude_list_struct *new_exclude;
374
1579bae1
AM
375 new_exclude = xmalloc (sizeof (struct exclude_list_struct));
376 new_exclude->string = xmalloc (strlen (exclude_string) + 1);
252b5132 377 strcpy (new_exclude->string, exclude_string);
70b0be79 378 new_exclude->type = type;
252b5132
RH
379 new_exclude->next = excludes;
380 excludes = new_exclude;
381 }
382
383 free (local_copy);
384}
385
70b0be79 386
775cabad
NC
387/* abfd is a bfd containing n (or NULL)
388 It can be used for contextual checks. */
389
252b5132 390static int
1579bae1 391auto_export (bfd *abfd, def_file *d, const char *n)
252b5132
RH
392{
393 int i;
394 struct exclude_list_struct *ex;
b044cda1 395 autofilter_entry_type *afptr;
70b0be79
CF
396 const char * libname = 0;
397 if (abfd && abfd->my_archive)
398 libname = lbasename (abfd->my_archive->filename);
b044cda1 399
775cabad 400 /* We should not re-export imported stuff. */
13ed4151 401 if (strncmp (n, "_imp_", 5) == 0)
b044cda1
CW
402 return 0;
403
252b5132
RH
404 for (i = 0; i < d->num_exports; i++)
405 if (strcmp (d->exports[i].name, n) == 0)
406 return 0;
775cabad 407
252b5132
RH
408 if (pe_dll_do_default_excludes)
409 {
663dd378 410 const char * p;
775cabad
NC
411 int len;
412
b044cda1 413 if (pe_dll_extra_pe_debug)
775cabad
NC
414 printf ("considering exporting: %s, abfd=%p, abfd->my_arc=%p\n",
415 n, abfd, abfd->my_archive);
b044cda1
CW
416
417 /* First of all, make context checks:
1579bae1 418 Don't export anything from standard libs. */
658957db 419 if (libname)
b044cda1
CW
420 {
421 afptr = autofilter_liblist;
775cabad 422
b044cda1
CW
423 while (afptr->name)
424 {
70b0be79 425 if (strncmp (libname, afptr->name, afptr->len) == 0 )
b044cda1
CW
426 return 0;
427 afptr++;
428 }
429 }
430
775cabad 431 /* Next, exclude symbols from certain startup objects. */
775cabad 432
59d28a94 433 if (abfd && (p = lbasename (abfd->filename)))
663dd378 434 {
b7a26f91
KH
435 afptr = autofilter_objlist;
436 while (afptr->name)
59d28a94 437 {
b7a26f91
KH
438 if (strcmp (p, afptr->name) == 0)
439 return 0;
59d28a94 440 afptr++;
663dd378 441 }
775cabad 442 }
b044cda1
CW
443
444 /* Don't try to blindly exclude all symbols
445 that begin with '__'; this was tried and
775cabad 446 it is too restrictive. */
b044cda1 447
775cabad 448 /* Then, exclude specific symbols. */
b044cda1
CW
449 afptr = autofilter_symbollist;
450 while (afptr->name)
451 {
452 if (strcmp (n, afptr->name) == 0)
453 return 0;
775cabad 454
b7a26f91 455 afptr++;
b044cda1
CW
456 }
457
775cabad 458 /* Next, exclude symbols starting with ... */
b044cda1
CW
459 afptr = autofilter_symbolprefixlist;
460 while (afptr->name)
461 {
462 if (strncmp (n, afptr->name, afptr->len) == 0)
463 return 0;
775cabad 464
b7a26f91 465 afptr++;
b044cda1
CW
466 }
467
775cabad
NC
468 /* Finally, exclude symbols ending with ... */
469 len = strlen (n);
470 afptr = autofilter_symbolsuffixlist;
471 while (afptr->name)
472 {
b7a26f91 473 if ((len >= afptr->len)
775cabad 474 /* Add 1 to insure match with trailing '\0'. */
b7a26f91
KH
475 && strncmp (n + len - afptr->len, afptr->name,
476 afptr->len + 1) == 0)
775cabad
NC
477 return 0;
478
b7a26f91 479 afptr++;
775cabad 480 }
252b5132 481 }
775cabad 482
252b5132 483 for (ex = excludes; ex; ex = ex->next)
70b0be79
CF
484 {
485 if (ex->type == 1) /* exclude-libs */
486 {
487 if (libname
488 && ((strcmp (libname, ex->string) == 0)
489 || (strcasecmp ("ALL", ex->string) == 0)))
490 return 0;
491 }
492 else if (strcmp (n, ex->string) == 0)
658957db 493 return 0;
70b0be79 494 }
775cabad 495
252b5132
RH
496 return 1;
497}
498
499static void
1579bae1 500process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
252b5132
RH
501{
502 int i, j;
503 struct bfd_link_hash_entry *blhe;
504 bfd *b;
198beae2 505 struct bfd_section *s;
d643799d 506 def_file_export *e = 0;
252b5132
RH
507
508 if (!pe_def_file)
509 pe_def_file = def_file_empty ();
510
511 /* First, run around to all the objects looking for the .drectve
86b1cc60 512 sections, and push those into the def file too. */
252b5132
RH
513 for (b = info->input_bfds; b; b = b->link_next)
514 {
515 s = bfd_get_section_by_name (b, ".drectve");
516 if (s)
517 {
eea6121a 518 long size = s->size;
252b5132 519 char *buf = xmalloc (size);
775cabad 520
252b5132
RH
521 bfd_get_section_contents (b, s, buf, 0, size);
522 def_file_add_directive (pe_def_file, buf, size);
523 free (buf);
524 }
525 }
526
2b817be1
NC
527 /* If we are not building a DLL, when there are no exports
528 we do not build an export table at all. */
529 if (!pe_dll_export_everything && pe_def_file->num_exports == 0
7b0eaa22 530 && info->executable)
2b817be1
NC
531 return;
532
86b1cc60 533 /* Now, maybe export everything else the default way. */
252b5132
RH
534 if (pe_dll_export_everything || pe_def_file->num_exports == 0)
535 {
536 for (b = info->input_bfds; b; b = b->link_next)
537 {
538 asymbol **symbols;
539 int nsyms, symsize;
540
541 symsize = bfd_get_symtab_upper_bound (b);
1579bae1 542 symbols = xmalloc (symsize);
252b5132
RH
543 nsyms = bfd_canonicalize_symtab (b, symbols);
544
545 for (j = 0; j < nsyms; j++)
546 {
d643799d 547 /* We should export symbols which are either global or not
1579bae1
AM
548 anything at all. (.bss data is the latter)
549 We should not export undefined symbols. */
b044cda1
CW
550 if (symbols[j]->section != &bfd_und_section
551 && ((symbols[j]->flags & BSF_GLOBAL)
552 || (symbols[j]->flags == BFD_FORT_COMM_DEFAULT_VALUE)))
252b5132
RH
553 {
554 const char *sn = symbols[j]->name;
b044cda1 555
775cabad 556 /* We should not re-export imported stuff. */
b044cda1 557 {
1579bae1 558 char *name = xmalloc (strlen (sn) + 2 + 6);
b044cda1 559 sprintf (name, "%s%s", U("_imp_"), sn);
775cabad 560
b044cda1 561 blhe = bfd_link_hash_lookup (info->hash, name,
b34976b6 562 FALSE, FALSE, FALSE);
b044cda1
CW
563 free (name);
564
b7a26f91 565 if (blhe && blhe->type == bfd_link_hash_defined)
b044cda1
CW
566 continue;
567 }
568
252b5132
RH
569 if (*sn == '_')
570 sn++;
775cabad 571
b044cda1
CW
572 if (auto_export (b, pe_def_file, sn))
573 {
574 def_file_export *p;
575 p=def_file_add_export (pe_def_file, sn, 0, -1);
775cabad 576 /* Fill data flag properly, from dlltool.c. */
b044cda1
CW
577 p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
578 }
252b5132
RH
579 }
580 }
581 }
582 }
583
584#undef NE
585#define NE pe_def_file->num_exports
586
86b1cc60 587 /* Canonicalize the export list. */
252b5132
RH
588 if (pe_dll_kill_ats)
589 {
590 for (i = 0; i < NE; i++)
591 {
592 if (strchr (pe_def_file->exports[i].name, '@'))
593 {
86b1cc60 594 /* This will preserve internal_name, which may have been
1579bae1
AM
595 pointing to the same memory as name, or might not
596 have. */
597 int lead_at = (*pe_def_file->exports[i].name == '@');
c9e38879 598 char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at);
775cabad 599
252b5132
RH
600 *(strchr (tmp, '@')) = 0;
601 pe_def_file->exports[i].name = tmp;
602 }
603 }
604 }
605
606 if (pe_dll_stdcall_aliases)
607 {
608 for (i = 0; i < NE; i++)
609 {
610 if (strchr (pe_def_file->exports[i].name, '@'))
611 {
1579bae1 612 int lead_at = (*pe_def_file->exports[i].name == '@');
c9e38879 613 char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at);
775cabad 614
252b5132 615 *(strchr (tmp, '@')) = 0;
b044cda1 616 if (auto_export (NULL, pe_def_file, tmp))
252b5132 617 def_file_add_export (pe_def_file, tmp,
b044cda1
CW
618 pe_def_file->exports[i].internal_name,
619 -1);
252b5132
RH
620 else
621 free (tmp);
622 }
623 }
624 }
625
86b1cc60
KH
626 /* Convenience, but watch out for it changing. */
627 e = pe_def_file->exports;
252b5132 628
1579bae1 629 exported_symbol_offsets = xmalloc (NE * sizeof (bfd_vma));
198beae2 630 exported_symbol_sections = xmalloc (NE * sizeof (struct bfd_section *));
252b5132 631
198beae2 632 memset (exported_symbol_sections, 0, NE * sizeof (struct bfd_section *));
252b5132
RH
633 max_ordinal = 0;
634 min_ordinal = 65536;
635 count_exported = 0;
636 count_exported_byname = 0;
637 count_with_ordinals = 0;
638
1579bae1
AM
639 qsort (pe_def_file->exports, NE, sizeof (pe_def_file->exports[0]),
640 pe_export_sort);
252b5132
RH
641 for (i = 0, j = 0; i < NE; i++)
642 {
643 if (i > 0 && strcmp (e[i].name, e[i - 1].name) == 0)
644 {
870df5dc 645 /* This is a duplicate. */
252b5132
RH
646 if (e[j - 1].ordinal != -1
647 && e[i].ordinal != -1
648 && e[j - 1].ordinal != e[i].ordinal)
649 {
870df5dc
NC
650 if (pe_dll_warn_dup_exports)
651 /* xgettext:c-format */
486e80e2 652 einfo (_("%XError, duplicate EXPORT with ordinals: %s (%d vs %d)\n"),
870df5dc 653 e[j - 1].name, e[j - 1].ordinal, e[i].ordinal);
252b5132
RH
654 }
655 else
656 {
870df5dc
NC
657 if (pe_dll_warn_dup_exports)
658 /* xgettext:c-format */
659 einfo (_("Warning, duplicate EXPORT: %s\n"),
660 e[j - 1].name);
252b5132 661 }
775cabad 662
486e80e2 663 if (e[i].ordinal != -1)
252b5132
RH
664 e[j - 1].ordinal = e[i].ordinal;
665 e[j - 1].flag_private |= e[i].flag_private;
666 e[j - 1].flag_constant |= e[i].flag_constant;
667 e[j - 1].flag_noname |= e[i].flag_noname;
668 e[j - 1].flag_data |= e[i].flag_data;
669 }
670 else
671 {
672 if (i != j)
673 e[j] = e[i];
674 j++;
675 }
676 }
677 pe_def_file->num_exports = j; /* == NE */
678
679 for (i = 0; i < NE; i++)
680 {
1579bae1 681 char *name;
775cabad 682
1579bae1 683 name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
c9e38879
NC
684 if (pe_details->underscored
685 && (*pe_def_file->exports[i].internal_name != '@'))
c6c37250
DD
686 {
687 *name = '_';
688 strcpy (name + 1, pe_def_file->exports[i].internal_name);
689 }
690 else
691 strcpy (name, pe_def_file->exports[i].internal_name);
252b5132
RH
692
693 blhe = bfd_link_hash_lookup (info->hash,
694 name,
b34976b6 695 FALSE, FALSE, TRUE);
252b5132 696
8a5b676c 697 if (blhe
d643799d 698 && (blhe->type == bfd_link_hash_defined
8a5b676c 699 || (blhe->type == bfd_link_hash_common)))
252b5132
RH
700 {
701 count_exported++;
702 if (!pe_def_file->exports[i].flag_noname)
703 count_exported_byname++;
8a5b676c
DD
704
705 /* Only fill in the sections. The actual offsets are computed
706 in fill_exported_offsets() after common symbols are laid
707 out. */
d643799d 708 if (blhe->type == bfd_link_hash_defined)
8a5b676c
DD
709 exported_symbol_sections[i] = blhe->u.def.section;
710 else
711 exported_symbol_sections[i] = blhe->u.c.p->section;
5cc18311 712
252b5132
RH
713 if (pe_def_file->exports[i].ordinal != -1)
714 {
715 if (max_ordinal < pe_def_file->exports[i].ordinal)
716 max_ordinal = pe_def_file->exports[i].ordinal;
717 if (min_ordinal > pe_def_file->exports[i].ordinal)
718 min_ordinal = pe_def_file->exports[i].ordinal;
719 count_with_ordinals++;
720 }
721 }
722 else if (blhe && blhe->type == bfd_link_hash_undefined)
723 {
724 /* xgettext:c-format */
725 einfo (_("%XCannot export %s: symbol not defined\n"),
726 pe_def_file->exports[i].internal_name);
727 }
728 else if (blhe)
729 {
730 /* xgettext:c-format */
731 einfo (_("%XCannot export %s: symbol wrong type (%d vs %d)\n"),
732 pe_def_file->exports[i].internal_name,
733 blhe->type, bfd_link_hash_defined);
734 }
735 else
736 {
737 /* xgettext:c-format */
738 einfo (_("%XCannot export %s: symbol not found\n"),
739 pe_def_file->exports[i].internal_name);
740 }
741 free (name);
742 }
743}
744
775cabad 745/* Build the bfd that will contain .edata and .reloc sections. */
252b5132
RH
746
747static void
1579bae1 748build_filler_bfd (int include_edata)
252b5132
RH
749{
750 lang_input_statement_type *filler_file;
751 filler_file = lang_add_input_file ("dll stuff",
752 lang_input_file_is_fake_enum,
753 NULL);
754 filler_file->the_bfd = filler_bfd = bfd_create ("dll stuff", output_bfd);
755 if (filler_bfd == NULL
756 || !bfd_set_arch_mach (filler_bfd,
757 bfd_get_arch (output_bfd),
758 bfd_get_mach (output_bfd)))
759 {
760 einfo ("%X%P: can not create BFD %E\n");
761 return;
762 }
763
c6c37250 764 if (include_edata)
252b5132 765 {
c6c37250
DD
766 edata_s = bfd_make_section_old_way (filler_bfd, ".edata");
767 if (edata_s == NULL
768 || !bfd_set_section_flags (filler_bfd, edata_s,
769 (SEC_HAS_CONTENTS
770 | SEC_ALLOC
771 | SEC_LOAD
772 | SEC_KEEP
773 | SEC_IN_MEMORY)))
774 {
775 einfo ("%X%P: can not create .edata section: %E\n");
776 return;
777 }
778 bfd_set_section_size (filler_bfd, edata_s, edata_sz);
252b5132 779 }
252b5132
RH
780
781 reloc_s = bfd_make_section_old_way (filler_bfd, ".reloc");
782 if (reloc_s == NULL
783 || !bfd_set_section_flags (filler_bfd, reloc_s,
784 (SEC_HAS_CONTENTS
785 | SEC_ALLOC
786 | SEC_LOAD
787 | SEC_KEEP
788 | SEC_IN_MEMORY)))
789 {
790 einfo ("%X%P: can not create .reloc section: %E\n");
791 return;
792 }
775cabad 793
252b5132
RH
794 bfd_set_section_size (filler_bfd, reloc_s, 0);
795
796 ldlang_add_file (filler_file);
797}
798
775cabad 799/* Gather all the exported symbols and build the .edata section. */
252b5132
RH
800
801static void
1579bae1 802generate_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
252b5132
RH
803{
804 int i, next_ordinal;
805 int name_table_size = 0;
806 const char *dlnp;
807
808 /* First, we need to know how many exported symbols there are,
5cc18311 809 and what the range of ordinals is. */
252b5132 810 if (pe_def_file->name)
775cabad 811 dll_name = pe_def_file->name;
252b5132
RH
812 else
813 {
814 dll_name = abfd->filename;
775cabad 815
252b5132 816 for (dlnp = dll_name; *dlnp; dlnp++)
775cabad
NC
817 if (*dlnp == '\\' || *dlnp == '/' || *dlnp == ':')
818 dll_name = dlnp + 1;
252b5132
RH
819 }
820
821 if (count_with_ordinals && max_ordinal > count_exported)
822 {
823 if (min_ordinal > max_ordinal - count_exported + 1)
824 min_ordinal = max_ordinal - count_exported + 1;
825 }
826 else
827 {
828 min_ordinal = 1;
829 max_ordinal = count_exported;
830 }
252b5132 831
775cabad 832 export_table_size = max_ordinal - min_ordinal + 1;
1579bae1 833 exported_symbols = xmalloc (export_table_size * sizeof (int));
252b5132
RH
834 for (i = 0; i < export_table_size; i++)
835 exported_symbols[i] = -1;
836
86b1cc60 837 /* Now we need to assign ordinals to those that don't have them. */
252b5132
RH
838 for (i = 0; i < NE; i++)
839 {
840 if (exported_symbol_sections[i])
841 {
842 if (pe_def_file->exports[i].ordinal != -1)
843 {
844 int ei = pe_def_file->exports[i].ordinal - min_ordinal;
845 int pi = exported_symbols[ei];
775cabad 846
252b5132
RH
847 if (pi != -1)
848 {
849 /* xgettext:c-format */
486e80e2 850 einfo (_("%XError, ordinal used twice: %d (%s vs %s)\n"),
252b5132
RH
851 pe_def_file->exports[i].ordinal,
852 pe_def_file->exports[i].name,
853 pe_def_file->exports[pi].name);
854 }
855 exported_symbols[ei] = i;
856 }
857 name_table_size += strlen (pe_def_file->exports[i].name) + 1;
858 }
859 }
860
861 next_ordinal = min_ordinal;
862 for (i = 0; i < NE; i++)
863 if (exported_symbol_sections[i])
864 if (pe_def_file->exports[i].ordinal == -1)
865 {
866 while (exported_symbols[next_ordinal - min_ordinal] != -1)
b7a26f91 867 next_ordinal++;
775cabad 868
252b5132
RH
869 exported_symbols[next_ordinal - min_ordinal] = i;
870 pe_def_file->exports[i].ordinal = next_ordinal;
871 }
872
86b1cc60 873 /* OK, now we can allocate some memory. */
775cabad
NC
874 edata_sz = (40 /* directory */
875 + 4 * export_table_size /* addresses */
252b5132
RH
876 + 4 * count_exported_byname /* name ptrs */
877 + 2 * count_exported_byname /* ordinals */
878 + name_table_size + strlen (dll_name) + 1);
879}
880
8a5b676c
DD
881/* Fill the exported symbol offsets. The preliminary work has already
882 been done in process_def_file(). */
883
884static void
1579bae1 885fill_exported_offsets (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
8a5b676c 886{
f0c87f88 887 int i;
8a5b676c 888 struct bfd_link_hash_entry *blhe;
5cc18311 889
8a5b676c
DD
890 for (i = 0; i < pe_def_file->num_exports; i++)
891 {
1579bae1 892 char *name;
775cabad 893
1579bae1 894 name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
c9e38879 895 if (pe_details->underscored
1579bae1 896 && *pe_def_file->exports[i].internal_name != '@')
8a5b676c
DD
897 {
898 *name = '_';
899 strcpy (name + 1, pe_def_file->exports[i].internal_name);
900 }
901 else
902 strcpy (name, pe_def_file->exports[i].internal_name);
903
904 blhe = bfd_link_hash_lookup (info->hash,
905 name,
b34976b6 906 FALSE, FALSE, TRUE);
8a5b676c 907
1579bae1 908 if (blhe && blhe->type == bfd_link_hash_defined)
775cabad
NC
909 exported_symbol_offsets[i] = blhe->u.def.value;
910
8a5b676c
DD
911 free (name);
912 }
913}
914
252b5132 915static void
1579bae1 916fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
252b5132 917{
03a1c9a7 918 int s, hint;
252b5132 919 unsigned char *edirectory;
2f9636ba
AM
920 unsigned char *eaddresses;
921 unsigned char *enameptrs;
922 unsigned char *eordinals;
47639182 923 char *enamestr;
252b5132
RH
924 time_t now;
925
926 time (&now);
927
1579bae1 928 edata_d = xmalloc (edata_sz);
252b5132 929
86b1cc60 930 /* Note use of array pointer math here. */
252b5132 931 edirectory = edata_d;
2f9636ba
AM
932 eaddresses = edata_d + 40;
933 enameptrs = eaddresses + 4 * export_table_size;
934 eordinals = enameptrs + 4 * count_exported_byname;
47639182 935 enamestr = (char *) eordinals + 2 * count_exported_byname;
252b5132 936
1579bae1
AM
937#define ERVA(ptr) (((unsigned char *)(ptr) - edata_d) \
938 + edata_s->output_section->vma - image_base)
252b5132 939
c2a94a7a 940 memset (edata_d, 0, edata_sz);
252b5132
RH
941 bfd_put_32 (abfd, now, edata_d + 4);
942 if (pe_def_file->version_major != -1)
943 {
944 bfd_put_16 (abfd, pe_def_file->version_major, edata_d + 8);
945 bfd_put_16 (abfd, pe_def_file->version_minor, edata_d + 10);
946 }
775cabad 947
252b5132
RH
948 bfd_put_32 (abfd, ERVA (enamestr), edata_d + 12);
949 strcpy (enamestr, dll_name);
950 enamestr += strlen (enamestr) + 1;
951 bfd_put_32 (abfd, min_ordinal, edata_d + 16);
952 bfd_put_32 (abfd, export_table_size, edata_d + 20);
953 bfd_put_32 (abfd, count_exported_byname, edata_d + 24);
954 bfd_put_32 (abfd, ERVA (eaddresses), edata_d + 28);
955 bfd_put_32 (abfd, ERVA (enameptrs), edata_d + 32);
956 bfd_put_32 (abfd, ERVA (eordinals), edata_d + 36);
957
8a5b676c
DD
958 fill_exported_offsets (abfd, info);
959
03a1c9a7
NC
960 /* Ok, now for the filling in part.
961 Scan alphabetically - ie the ordering in the exports[] table,
962 rather than by ordinal - the ordering in the exported_symbol[]
963 table. See dlltool.c and:
964 http://sources.redhat.com/ml/binutils/2003-04/msg00379.html
1579bae1 965 for more information. */
252b5132 966 hint = 0;
03a1c9a7 967 for (s = 0; s < NE; s++)
252b5132 968 {
f5a95868
DS
969 struct bfd_section *ssec = exported_symbol_sections[s];
970 if (ssec && pe_def_file->exports[s].ordinal != -1)
252b5132 971 {
252b5132
RH
972 unsigned long srva = (exported_symbol_offsets[s]
973 + ssec->output_section->vma
974 + ssec->output_offset);
45b1f63c 975 int ord = pe_def_file->exports[s].ordinal;
252b5132 976
45b1f63c 977 bfd_put_32 (abfd, srva - image_base,
2f9636ba 978 eaddresses + 4 * (ord - min_ordinal));
775cabad 979
252b5132
RH
980 if (!pe_def_file->exports[s].flag_noname)
981 {
982 char *ename = pe_def_file->exports[s].name;
03a1c9a7 983
2f9636ba
AM
984 bfd_put_32 (abfd, ERVA (enamestr), enameptrs);
985 enameptrs += 4;
252b5132
RH
986 strcpy (enamestr, ename);
987 enamestr += strlen (enamestr) + 1;
2f9636ba
AM
988 bfd_put_16 (abfd, ord - min_ordinal, eordinals);
989 eordinals += 2;
252b5132
RH
990 pe_def_file->exports[s].hint = hint++;
991 }
252b5132
RH
992 }
993 }
994}
995
b044cda1 996
198beae2 997static struct bfd_section *current_sec;
b044cda1
CW
998
999void
1579bae1
AM
1000pe_walk_relocs_of_symbol (struct bfd_link_info *info,
1001 const char *name,
1002 int (*cb) (arelent *, asection *))
b044cda1
CW
1003{
1004 bfd *b;
0d888aac 1005 asection *s;
b044cda1
CW
1006
1007 for (b = info->input_bfds; b; b = b->link_next)
1008 {
775cabad
NC
1009 asymbol **symbols;
1010 int nsyms, symsize;
1011
1012 symsize = bfd_get_symtab_upper_bound (b);
1579bae1 1013 symbols = xmalloc (symsize);
775cabad 1014 nsyms = bfd_canonicalize_symtab (b, symbols);
b044cda1
CW
1015
1016 for (s = b->sections; s; s = s->next)
1017 {
775cabad
NC
1018 arelent **relocs;
1019 int relsize, nrelocs, i;
b044cda1
CW
1020 int flags = bfd_get_section_flags (b, s);
1021
775cabad 1022 /* Skip discarded linkonce sections. */
b044cda1
CW
1023 if (flags & SEC_LINK_ONCE
1024 && s->output_section == bfd_abs_section_ptr)
1025 continue;
1026
0d888aac 1027 current_sec = s;
b044cda1 1028
b044cda1 1029 relsize = bfd_get_reloc_upper_bound (b, s);
1579bae1 1030 relocs = xmalloc (relsize);
b044cda1
CW
1031 nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);
1032
1033 for (i = 0; i < nrelocs; i++)
1034 {
fc0a2244 1035 struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
775cabad
NC
1036
1037 if (!strcmp (name, sym->name))
1038 cb (relocs[i], s);
b044cda1 1039 }
775cabad 1040
b044cda1 1041 free (relocs);
775cabad 1042
b044cda1
CW
1043 /* Warning: the allocated symbols are remembered in BFD and reused
1044 later, so don't free them! */
1045 /* free (symbols); */
1046 }
1047 }
1048}
1049
775cabad 1050/* Gather all the relocations and build the .reloc section. */
252b5132
RH
1051
1052static void
1579bae1 1053generate_reloc (bfd *abfd, struct bfd_link_info *info)
252b5132
RH
1054{
1055
86b1cc60 1056 /* For .reloc stuff. */
c6c37250 1057 reloc_data_type *reloc_data;
252b5132
RH
1058 int total_relocs = 0;
1059 int i;
1579bae1 1060 unsigned long sec_page = (unsigned long) -1;
252b5132
RH
1061 unsigned long page_ptr, page_count;
1062 int bi;
1063 bfd *b;
198beae2 1064 struct bfd_section *s;
252b5132
RH
1065
1066 total_relocs = 0;
1067 for (b = info->input_bfds; b; b = b->link_next)
1068 for (s = b->sections; s; s = s->next)
1069 total_relocs += s->reloc_count;
1070
1579bae1 1071 reloc_data = xmalloc (total_relocs * sizeof (reloc_data_type));
252b5132
RH
1072
1073 total_relocs = 0;
1074 bi = 0;
1075 for (bi = 0, b = info->input_bfds; b; bi++, b = b->link_next)
1076 {
1077 arelent **relocs;
1078 int relsize, nrelocs, i;
1079
1080 for (s = b->sections; s; s = s->next)
1081 {
1082 unsigned long sec_vma = s->output_section->vma + s->output_offset;
1083 asymbol **symbols;
1084 int nsyms, symsize;
1085
86b1cc60 1086 /* If it's not loaded, we don't need to relocate it this way. */
252b5132
RH
1087 if (!(s->output_section->flags & SEC_LOAD))
1088 continue;
1089
1090 /* I don't know why there would be a reloc for these, but I've
86b1cc60 1091 seen it happen - DJ */
252b5132
RH
1092 if (s->output_section == &bfd_abs_section)
1093 continue;
1094
1095 if (s->output_section->vma == 0)
1096 {
86b1cc60 1097 /* Huh? Shouldn't happen, but punt if it does. */
252b5132
RH
1098 einfo ("DJ: zero vma section reloc detected: `%s' #%d f=%d\n",
1099 s->output_section->name, s->output_section->index,
1100 s->output_section->flags);
1101 continue;
1102 }
1103
1104 symsize = bfd_get_symtab_upper_bound (b);
1579bae1 1105 symbols = xmalloc (symsize);
252b5132
RH
1106 nsyms = bfd_canonicalize_symtab (b, symbols);
1107
1108 relsize = bfd_get_reloc_upper_bound (b, s);
1579bae1 1109 relocs = xmalloc (relsize);
252b5132
RH
1110 nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);
1111
1112 for (i = 0; i < nrelocs; i++)
1113 {
b044cda1 1114 if (pe_dll_extra_pe_debug)
b7a26f91 1115 {
fc0a2244 1116 struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
b7a26f91 1117 printf ("rel: %s\n", sym->name);
b044cda1 1118 }
252b5132 1119 if (!relocs[i]->howto->pc_relative
c6c37250 1120 && relocs[i]->howto->type != pe_details->imagebase_reloc)
252b5132 1121 {
c6c37250 1122 bfd_vma sym_vma;
fc0a2244 1123 struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
775cabad 1124
c6c37250
DD
1125 sym_vma = (relocs[i]->addend
1126 + sym->value
1127 + sym->section->vma
1128 + sym->section->output_offset
1129 + sym->section->output_section->vma);
1130 reloc_data[total_relocs].vma = sec_vma + relocs[i]->address;
5cc18311 1131
344a211f 1132#define BITS_AND_SHIFT(bits, shift) (bits * 1000 | shift)
5cc18311 1133
344a211f
NC
1134 switch BITS_AND_SHIFT (relocs[i]->howto->bitsize,
1135 relocs[i]->howto->rightshift)
252b5132 1136 {
344a211f 1137 case BITS_AND_SHIFT (32, 0):
c6c37250
DD
1138 reloc_data[total_relocs].type = 3;
1139 total_relocs++;
252b5132 1140 break;
344a211f
NC
1141 case BITS_AND_SHIFT (16, 0):
1142 reloc_data[total_relocs].type = 2;
1143 total_relocs++;
1144 break;
1145 case BITS_AND_SHIFT (16, 16):
1146 reloc_data[total_relocs].type = 4;
86b1cc60
KH
1147 /* FIXME: we can't know the symbol's right value
1148 yet, but we probably can safely assume that
1149 CE will relocate us in 64k blocks, so leaving
1150 it zero is safe. */
344a211f
NC
1151 reloc_data[total_relocs].extra = 0;
1152 total_relocs++;
1153 break;
1154 case BITS_AND_SHIFT (26, 2):
1155 reloc_data[total_relocs].type = 5;
1156 total_relocs++;
1157 break;
fea39bcb 1158 case BITS_AND_SHIFT (24, 2):
d3793eaa
NC
1159 /* FIXME: 0 is ARM_26D, it is defined in bfd/coff-arm.c
1160 Those ARM_xxx definitions should go in proper
1161 header someday. */
1162 if (relocs[i]->howto->type == 0
1163 /* Older GNU linkers used 5 instead of 0 for this reloc. */
1164 || relocs[i]->howto->type == 5)
fea39bcb
NC
1165 /* This is an ARM_26D reloc, which is an ARM_26 reloc
1166 that has already been fully processed during a
1167 previous link stage, so ignore it here. */
1168 break;
1169 /* Fall through. */
252b5132
RH
1170 default:
1171 /* xgettext:c-format */
1172 einfo (_("%XError: %d-bit reloc in dll\n"),
1173 relocs[i]->howto->bitsize);
1174 break;
1175 }
1176 }
1177 }
1178 free (relocs);
86b1cc60
KH
1179 /* Warning: the allocated symbols are remembered in BFD and
1180 reused later, so don't free them! */
252b5132
RH
1181 }
1182 }
1183
1184 /* At this point, we have total_relocs relocation addresses in
1185 reloc_addresses, which are all suitable for the .reloc section.
5cc18311 1186 We must now create the new sections. */
c6c37250 1187 qsort (reloc_data, total_relocs, sizeof (*reloc_data), reloc_sort);
252b5132
RH
1188
1189 for (i = 0; i < total_relocs; i++)
1190 {
c6c37250 1191 unsigned long this_page = (reloc_data[i].vma >> 12);
5cc18311 1192
252b5132
RH
1193 if (this_page != sec_page)
1194 {
775cabad 1195 reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align. */
252b5132
RH
1196 reloc_sz += 8;
1197 sec_page = this_page;
1198 }
5cc18311 1199
252b5132 1200 reloc_sz += 2;
5cc18311 1201
344a211f
NC
1202 if (reloc_data[i].type == 4)
1203 reloc_sz += 2;
252b5132 1204 }
b7a26f91 1205
775cabad 1206 reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align. */
1579bae1
AM
1207 reloc_d = xmalloc (reloc_sz);
1208 sec_page = (unsigned long) -1;
252b5132 1209 reloc_sz = 0;
1579bae1 1210 page_ptr = (unsigned long) -1;
252b5132 1211 page_count = 0;
775cabad 1212
252b5132
RH
1213 for (i = 0; i < total_relocs; i++)
1214 {
c6c37250 1215 unsigned long rva = reloc_data[i].vma - image_base;
252b5132 1216 unsigned long this_page = (rva & ~0xfff);
775cabad 1217
252b5132
RH
1218 if (this_page != sec_page)
1219 {
1220 while (reloc_sz & 3)
1221 reloc_d[reloc_sz++] = 0;
775cabad 1222
1579bae1 1223 if (page_ptr != (unsigned long) -1)
252b5132 1224 bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
775cabad 1225
252b5132
RH
1226 bfd_put_32 (abfd, this_page, reloc_d + reloc_sz);
1227 page_ptr = reloc_sz;
1228 reloc_sz += 8;
1229 sec_page = this_page;
1230 page_count = 0;
1231 }
775cabad 1232
d643799d 1233 bfd_put_16 (abfd, (rva & 0xfff) + (reloc_data[i].type << 12),
c6c37250 1234 reloc_d + reloc_sz);
252b5132 1235 reloc_sz += 2;
775cabad 1236
c6c37250
DD
1237 if (reloc_data[i].type == 4)
1238 {
1239 bfd_put_16 (abfd, reloc_data[i].extra, reloc_d + reloc_sz);
1240 reloc_sz += 2;
1241 }
775cabad 1242
252b5132
RH
1243 page_count++;
1244 }
775cabad 1245
252b5132
RH
1246 while (reloc_sz & 3)
1247 reloc_d[reloc_sz++] = 0;
775cabad 1248
1579bae1 1249 if (page_ptr != (unsigned long) -1)
252b5132 1250 bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
775cabad 1251
eea6121a 1252 while (reloc_sz < reloc_s->size)
252b5132
RH
1253 reloc_d[reloc_sz++] = 0;
1254}
1255
775cabad
NC
1256/* Given the exiting def_file structure, print out a .DEF file that
1257 corresponds to it. */
252b5132
RH
1258
1259static void
1579bae1 1260quoteput (char *s, FILE *f, int needs_quotes)
252b5132
RH
1261{
1262 char *cp;
775cabad 1263
252b5132
RH
1264 for (cp = s; *cp; cp++)
1265 if (*cp == '\''
1266 || *cp == '"'
1267 || *cp == '\\'
3882b010 1268 || ISSPACE (*cp)
252b5132
RH
1269 || *cp == ','
1270 || *cp == ';')
1271 needs_quotes = 1;
775cabad 1272
252b5132
RH
1273 if (needs_quotes)
1274 {
1275 putc ('"', f);
775cabad 1276
252b5132
RH
1277 while (*s)
1278 {
1279 if (*s == '"' || *s == '\\')
1280 putc ('\\', f);
775cabad 1281
252b5132
RH
1282 putc (*s, f);
1283 s++;
1284 }
775cabad 1285
252b5132
RH
1286 putc ('"', f);
1287 }
1288 else
1289 fputs (s, f);
1290}
1291
1292void
1579bae1 1293pe_dll_generate_def_file (const char *pe_out_def_filename)
252b5132
RH
1294{
1295 int i;
1296 FILE *out = fopen (pe_out_def_filename, "w");
775cabad 1297
252b5132 1298 if (out == NULL)
775cabad
NC
1299 /* xgettext:c-format */
1300 einfo (_("%s: Can't open output def file %s\n"),
1301 program_name, pe_out_def_filename);
252b5132
RH
1302
1303 if (pe_def_file)
1304 {
1305 if (pe_def_file->name)
1306 {
1307 if (pe_def_file->is_dll)
1308 fprintf (out, "LIBRARY ");
1309 else
1310 fprintf (out, "NAME ");
775cabad 1311
252b5132 1312 quoteput (pe_def_file->name, out, 1);
775cabad 1313
252b5132
RH
1314 if (pe_data (output_bfd)->pe_opthdr.ImageBase)
1315 fprintf (out, " BASE=0x%lx",
1316 (unsigned long) pe_data (output_bfd)->pe_opthdr.ImageBase);
1317 fprintf (out, "\n");
1318 }
1319
1320 if (pe_def_file->description)
1321 {
1322 fprintf (out, "DESCRIPTION ");
1323 quoteput (pe_def_file->description, out, 1);
1324 fprintf (out, "\n");
1325 }
1326
1327 if (pe_def_file->version_minor != -1)
1328 fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major,
1329 pe_def_file->version_minor);
1330 else if (pe_def_file->version_major != -1)
1331 fprintf (out, "VERSION %d\n", pe_def_file->version_major);
1332
1333 if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1)
1334 fprintf (out, "\n");
1335
1336 if (pe_def_file->stack_commit != -1)
1337 fprintf (out, "STACKSIZE 0x%x,0x%x\n",
1338 pe_def_file->stack_reserve, pe_def_file->stack_commit);
1339 else if (pe_def_file->stack_reserve != -1)
1340 fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve);
775cabad 1341
252b5132
RH
1342 if (pe_def_file->heap_commit != -1)
1343 fprintf (out, "HEAPSIZE 0x%x,0x%x\n",
1344 pe_def_file->heap_reserve, pe_def_file->heap_commit);
1345 else if (pe_def_file->heap_reserve != -1)
1346 fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve);
1347
1348 if (pe_def_file->num_section_defs > 0)
1349 {
1350 fprintf (out, "\nSECTIONS\n\n");
775cabad 1351
252b5132
RH
1352 for (i = 0; i < pe_def_file->num_section_defs; i++)
1353 {
1354 fprintf (out, " ");
1355 quoteput (pe_def_file->section_defs[i].name, out, 0);
775cabad 1356
252b5132
RH
1357 if (pe_def_file->section_defs[i].class)
1358 {
1359 fprintf (out, " CLASS ");
1360 quoteput (pe_def_file->section_defs[i].class, out, 0);
1361 }
775cabad 1362
252b5132
RH
1363 if (pe_def_file->section_defs[i].flag_read)
1364 fprintf (out, " READ");
775cabad 1365
252b5132
RH
1366 if (pe_def_file->section_defs[i].flag_write)
1367 fprintf (out, " WRITE");
775cabad 1368
252b5132
RH
1369 if (pe_def_file->section_defs[i].flag_execute)
1370 fprintf (out, " EXECUTE");
775cabad 1371
252b5132
RH
1372 if (pe_def_file->section_defs[i].flag_shared)
1373 fprintf (out, " SHARED");
775cabad 1374
252b5132
RH
1375 fprintf (out, "\n");
1376 }
1377 }
1378
1379 if (pe_def_file->num_exports > 0)
1380 {
b044cda1 1381 fprintf (out, "EXPORTS\n");
775cabad 1382
252b5132
RH
1383 for (i = 0; i < pe_def_file->num_exports; i++)
1384 {
1385 def_file_export *e = pe_def_file->exports + i;
1386 fprintf (out, " ");
1387 quoteput (e->name, out, 0);
775cabad 1388
252b5132
RH
1389 if (e->internal_name && strcmp (e->internal_name, e->name))
1390 {
1391 fprintf (out, " = ");
1392 quoteput (e->internal_name, out, 0);
1393 }
775cabad 1394
252b5132
RH
1395 if (e->ordinal != -1)
1396 fprintf (out, " @%d", e->ordinal);
775cabad 1397
252b5132
RH
1398 if (e->flag_private)
1399 fprintf (out, " PRIVATE");
775cabad 1400
252b5132
RH
1401 if (e->flag_constant)
1402 fprintf (out, " CONSTANT");
775cabad 1403
252b5132
RH
1404 if (e->flag_noname)
1405 fprintf (out, " NONAME");
775cabad 1406
252b5132
RH
1407 if (e->flag_data)
1408 fprintf (out, " DATA");
1409
1410 fprintf (out, "\n");
1411 }
1412 }
1413
1414 if (pe_def_file->num_imports > 0)
1415 {
1416 fprintf (out, "\nIMPORTS\n\n");
775cabad 1417
252b5132
RH
1418 for (i = 0; i < pe_def_file->num_imports; i++)
1419 {
1420 def_file_import *im = pe_def_file->imports + i;
1421 fprintf (out, " ");
775cabad 1422
252b5132
RH
1423 if (im->internal_name
1424 && (!im->name || strcmp (im->internal_name, im->name)))
1425 {
1426 quoteput (im->internal_name, out, 0);
1427 fprintf (out, " = ");
1428 }
775cabad 1429
252b5132
RH
1430 quoteput (im->module->name, out, 0);
1431 fprintf (out, ".");
775cabad 1432
252b5132
RH
1433 if (im->name)
1434 quoteput (im->name, out, 0);
1435 else
1436 fprintf (out, "%d", im->ordinal);
775cabad 1437
252b5132
RH
1438 fprintf (out, "\n");
1439 }
1440 }
1441 }
1442 else
1443 fprintf (out, _("; no contents available\n"));
1444
1445 if (fclose (out) == EOF)
775cabad
NC
1446 /* xgettext:c-format */
1447 einfo (_("%P: Error closing file `%s'\n"), pe_out_def_filename);
252b5132
RH
1448}
1449
775cabad 1450/* Generate the import library. */
252b5132
RH
1451
1452static asymbol **symtab;
1453static int symptr;
1454static int tmp_seq;
1455static const char *dll_filename;
1456static char *dll_symname;
1457
1458#define UNDSEC (asection *) &bfd_und_section
1459
1460static asection *
1579bae1 1461quick_section (bfd *abfd, const char *name, int flags, int align)
252b5132
RH
1462{
1463 asection *sec;
1464 asymbol *sym;
1465
1466 sec = bfd_make_section_old_way (abfd, name);
86b1cc60 1467 bfd_set_section_flags (abfd, sec, flags | SEC_ALLOC | SEC_LOAD | SEC_KEEP);
252b5132 1468 bfd_set_section_alignment (abfd, sec, align);
86b1cc60 1469 /* Remember to undo this before trying to link internally! */
252b5132
RH
1470 sec->output_section = sec;
1471
1472 sym = bfd_make_empty_symbol (abfd);
1473 symtab[symptr++] = sym;
1474 sym->name = sec->name;
1475 sym->section = sec;
1476 sym->flags = BSF_LOCAL;
1477 sym->value = 0;
1478
1479 return sec;
1480}
1481
1482static void
1579bae1
AM
1483quick_symbol (bfd *abfd,
1484 const char *n1,
1485 const char *n2,
1486 const char *n3,
1487 asection *sec,
1488 int flags,
1489 int addr)
252b5132
RH
1490{
1491 asymbol *sym;
1579bae1 1492 char *name = xmalloc (strlen (n1) + strlen (n2) + strlen (n3) + 1);
775cabad 1493
252b5132
RH
1494 strcpy (name, n1);
1495 strcat (name, n2);
1496 strcat (name, n3);
1497 sym = bfd_make_empty_symbol (abfd);
1498 sym->name = name;
1499 sym->section = sec;
1500 sym->flags = flags;
1501 sym->value = addr;
1502 symtab[symptr++] = sym;
1503}
1504
1505static arelent *reltab = 0;
1506static int relcount = 0, relsize = 0;
1507
1508static void
1579bae1 1509quick_reloc (bfd *abfd, int address, int which_howto, int symidx)
252b5132 1510{
1579bae1 1511 if (relcount >= relsize - 1)
252b5132
RH
1512 {
1513 relsize += 10;
1514 if (reltab)
1579bae1 1515 reltab = xrealloc (reltab, relsize * sizeof (arelent));
252b5132 1516 else
1579bae1 1517 reltab = xmalloc (relsize * sizeof (arelent));
252b5132
RH
1518 }
1519 reltab[relcount].address = address;
1520 reltab[relcount].addend = 0;
1521 reltab[relcount].howto = bfd_reloc_type_lookup (abfd, which_howto);
1522 reltab[relcount].sym_ptr_ptr = symtab + symidx;
1523 relcount++;
1524}
1525
1526static void
1527save_relocs (asection *sec)
1528{
1529 int i;
775cabad 1530
252b5132
RH
1531 sec->relocation = reltab;
1532 sec->reloc_count = relcount;
1579bae1 1533 sec->orelocation = xmalloc ((relcount + 1) * sizeof (arelent *));
d643799d 1534 for (i = 0; i < relcount; i++)
252b5132
RH
1535 sec->orelocation[i] = sec->relocation + i;
1536 sec->orelocation[relcount] = 0;
1537 sec->flags |= SEC_RELOC;
1538 reltab = 0;
1539 relcount = relsize = 0;
1540}
1541
775cabad
NC
1542/* .section .idata$2
1543 .global __head_my_dll
1544 __head_my_dll:
1545 .rva hname
1546 .long 0
1547 .long 0
1548 .rva __my_dll_iname
1549 .rva fthunk
b7a26f91 1550
775cabad
NC
1551 .section .idata$5
1552 .long 0
1553 fthunk:
b7a26f91 1554
775cabad
NC
1555 .section .idata$4
1556 .long 0
1557 hname: */
252b5132
RH
1558
1559static bfd *
1579bae1 1560make_head (bfd *parent)
252b5132
RH
1561{
1562 asection *id2, *id5, *id4;
1563 unsigned char *d2, *d5, *d4;
1564 char *oname;
1565 bfd *abfd;
1566
1579bae1 1567 oname = xmalloc (20);
252b5132
RH
1568 sprintf (oname, "d%06d.o", tmp_seq);
1569 tmp_seq++;
1570
1571 abfd = bfd_create (oname, parent);
c6c37250 1572 bfd_find_target (pe_details->object_target, abfd);
252b5132
RH
1573 bfd_make_writable (abfd);
1574
1575 bfd_set_format (abfd, bfd_object);
c6c37250 1576 bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
252b5132
RH
1577
1578 symptr = 0;
1579bae1 1579 symtab = xmalloc (6 * sizeof (asymbol *));
252b5132
RH
1580 id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
1581 id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
1582 id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
d643799d
KH
1583 quick_symbol (abfd, U ("_head_"), dll_symname, "", id2, BSF_GLOBAL, 0);
1584 quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
c6c37250
DD
1585
1586 /* OK, pay attention here. I got confused myself looking back at
1587 it. We create a four-byte section to mark the beginning of the
1588 list, and we include an offset of 4 in the section, so that the
1589 pointer to the list points to the *end* of this section, which is
5cc18311 1590 the start of the list of sections from other objects. */
252b5132
RH
1591
1592 bfd_set_section_size (abfd, id2, 20);
1579bae1 1593 d2 = xmalloc (20);
252b5132
RH
1594 id2->contents = d2;
1595 memset (d2, 0, 20);
775cabad 1596 d2[0] = d2[16] = 4; /* Reloc addend. */
252b5132
RH
1597 quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
1598 quick_reloc (abfd, 12, BFD_RELOC_RVA, 4);
1599 quick_reloc (abfd, 16, BFD_RELOC_RVA, 1);
1600 save_relocs (id2);
1601
1602 bfd_set_section_size (abfd, id5, 4);
1579bae1 1603 d5 = xmalloc (4);
252b5132
RH
1604 id5->contents = d5;
1605 memset (d5, 0, 4);
1606
1607 bfd_set_section_size (abfd, id4, 4);
1579bae1 1608 d4 = xmalloc (4);
252b5132
RH
1609 id4->contents = d4;
1610 memset (d4, 0, 4);
1611
1612 bfd_set_symtab (abfd, symtab, symptr);
1613
1614 bfd_set_section_contents (abfd, id2, d2, 0, 20);
1615 bfd_set_section_contents (abfd, id5, d5, 0, 4);
1616 bfd_set_section_contents (abfd, id4, d4, 0, 4);
5cc18311 1617
252b5132
RH
1618 bfd_make_readable (abfd);
1619 return abfd;
1620}
1621
775cabad
NC
1622/* .section .idata$4
1623 .long 0
1624 .section .idata$5
1625 .long 0
1626 .section idata$7
1627 .global __my_dll_iname
1628 __my_dll_iname:
1629 .asciz "my.dll" */
252b5132
RH
1630
1631static bfd *
1579bae1 1632make_tail (bfd *parent)
252b5132
RH
1633{
1634 asection *id4, *id5, *id7;
1635 unsigned char *d4, *d5, *d7;
1636 int len;
1637 char *oname;
1638 bfd *abfd;
1639
1579bae1 1640 oname = xmalloc (20);
252b5132
RH
1641 sprintf (oname, "d%06d.o", tmp_seq);
1642 tmp_seq++;
1643
1644 abfd = bfd_create (oname, parent);
c6c37250 1645 bfd_find_target (pe_details->object_target, abfd);
252b5132
RH
1646 bfd_make_writable (abfd);
1647
1648 bfd_set_format (abfd, bfd_object);
c6c37250 1649 bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
252b5132
RH
1650
1651 symptr = 0;
1579bae1 1652 symtab = xmalloc (5 * sizeof (asymbol *));
252b5132
RH
1653 id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
1654 id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
1655 id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
d643799d 1656 quick_symbol (abfd, U (""), dll_symname, "_iname", id7, BSF_GLOBAL, 0);
252b5132
RH
1657
1658 bfd_set_section_size (abfd, id4, 4);
1579bae1 1659 d4 = xmalloc (4);
252b5132
RH
1660 id4->contents = d4;
1661 memset (d4, 0, 4);
1662
1663 bfd_set_section_size (abfd, id5, 4);
1579bae1 1664 d5 = xmalloc (4);
252b5132
RH
1665 id5->contents = d5;
1666 memset (d5, 0, 4);
1667
d643799d 1668 len = strlen (dll_filename) + 1;
252b5132 1669 if (len & 1)
d643799d 1670 len++;
252b5132 1671 bfd_set_section_size (abfd, id7, len);
1579bae1 1672 d7 = xmalloc (len);
252b5132 1673 id7->contents = d7;
47639182 1674 strcpy ((char *) d7, dll_filename);
252b5132
RH
1675
1676 bfd_set_symtab (abfd, symtab, symptr);
1677
1678 bfd_set_section_contents (abfd, id4, d4, 0, 4);
1679 bfd_set_section_contents (abfd, id5, d5, 0, 4);
1680 bfd_set_section_contents (abfd, id7, d7, 0, len);
1681
1682 bfd_make_readable (abfd);
1683 return abfd;
1684}
1685
775cabad
NC
1686/* .text
1687 .global _function
1688 .global ___imp_function
1689 .global __imp__function
1690 _function:
1691 jmp *__imp__function:
b7a26f91 1692
775cabad
NC
1693 .section idata$7
1694 .long __head_my_dll
b7a26f91 1695
775cabad
NC
1696 .section .idata$5
1697 ___imp_function:
1698 __imp__function:
1699 iat?
1700 .section .idata$4
1701 iat?
1702 .section .idata$6
1703 ID<ordinal>:
1704 .short <hint>
1705 .asciz "function" xlate? (add underscore, kill at) */
1706
1707static unsigned char jmp_ix86_bytes[] =
1708{
252b5132
RH
1709 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
1710};
1711
775cabad
NC
1712/* _function:
1713 mov.l ip+8,r0
1714 mov.l @r0,r0
1715 jmp @r0
1716 nop
1717 .dw __imp_function */
344a211f 1718
775cabad
NC
1719static unsigned char jmp_sh_bytes[] =
1720{
344a211f
NC
1721 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00
1722};
1723
775cabad
NC
1724/* _function:
1725 lui $t0,<high:__imp_function>
1726 lw $t0,<low:__imp_function>
1727 jr $t0
1728 nop */
344a211f 1729
775cabad
NC
1730static unsigned char jmp_mips_bytes[] =
1731{
344a211f
NC
1732 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
1733 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
1734};
252b5132
RH
1735
1736static bfd *
1579bae1 1737make_one (def_file_export *exp, bfd *parent)
252b5132
RH
1738{
1739 asection *tx, *id7, *id5, *id4, *id6;
23a87948 1740 unsigned char *td = NULL, *d7, *d5, *d4, *d6 = NULL;
252b5132
RH
1741 int len;
1742 char *oname;
1743 bfd *abfd;
f0c87f88
NC
1744 unsigned char *jmp_bytes = NULL;
1745 int jmp_byte_count = 0;
c6c37250
DD
1746
1747 switch (pe_details->pe_arch)
1748 {
1749 case PE_ARCH_i386:
1750 jmp_bytes = jmp_ix86_bytes;
1751 jmp_byte_count = sizeof (jmp_ix86_bytes);
1752 break;
344a211f
NC
1753 case PE_ARCH_sh:
1754 jmp_bytes = jmp_sh_bytes;
1755 jmp_byte_count = sizeof (jmp_sh_bytes);
1756 break;
1757 case PE_ARCH_mips:
1758 jmp_bytes = jmp_mips_bytes;
1759 jmp_byte_count = sizeof (jmp_mips_bytes);
1760 break;
775cabad
NC
1761 default:
1762 abort ();
c6c37250 1763 }
252b5132 1764
1579bae1 1765 oname = xmalloc (20);
252b5132
RH
1766 sprintf (oname, "d%06d.o", tmp_seq);
1767 tmp_seq++;
1768
1769 abfd = bfd_create (oname, parent);
c6c37250 1770 bfd_find_target (pe_details->object_target, abfd);
252b5132
RH
1771 bfd_make_writable (abfd);
1772
1773 bfd_set_format (abfd, bfd_object);
c6c37250 1774 bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
252b5132
RH
1775
1776 symptr = 0;
1579bae1 1777 symtab = xmalloc (11 * sizeof (asymbol *));
252b5132
RH
1778 tx = quick_section (abfd, ".text", SEC_CODE|SEC_HAS_CONTENTS, 2);
1779 id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
1780 id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
1781 id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
1782 id6 = quick_section (abfd, ".idata$6", SEC_HAS_CONTENTS, 2);
b34976b6 1783
c9e38879
NC
1784 if (*exp->internal_name == '@')
1785 {
1579bae1
AM
1786 quick_symbol (abfd, U ("_head_"), dll_symname, "", UNDSEC,
1787 BSF_GLOBAL, 0);
4b7f0676
NC
1788 if (! exp->flag_data)
1789 quick_symbol (abfd, "", exp->internal_name, "", tx, BSF_GLOBAL, 0);
1579bae1
AM
1790 quick_symbol (abfd, U ("_imp_"), exp->internal_name, "", id5,
1791 BSF_GLOBAL, 0);
c9e38879
NC
1792 /* Fastcall applies only to functions,
1793 so no need for auto-import symbol. */
1794 }
1795 else
1796 {
4b7f0676
NC
1797 quick_symbol (abfd, U ("_head_"), dll_symname, "", UNDSEC,
1798 BSF_GLOBAL, 0);
c9e38879 1799 if (! exp->flag_data)
1579bae1
AM
1800 quick_symbol (abfd, U (""), exp->internal_name, "", tx,
1801 BSF_GLOBAL, 0);
1579bae1
AM
1802 quick_symbol (abfd, U ("_imp__"), exp->internal_name, "", id5,
1803 BSF_GLOBAL, 0);
c9e38879 1804 /* Symbol to reference ord/name of imported
1579bae1 1805 data symbol, used to implement auto-import. */
c9e38879 1806 if (exp->flag_data)
1579bae1
AM
1807 quick_symbol (abfd, U("_nm__"), exp->internal_name, "", id6,
1808 BSF_GLOBAL,0);
c9e38879 1809 }
870df5dc 1810 if (pe_dll_compat_implib)
1579bae1
AM
1811 quick_symbol (abfd, U ("__imp_"), exp->internal_name, "", id5,
1812 BSF_GLOBAL, 0);
252b5132 1813
23a87948 1814 if (! exp->flag_data)
775cabad
NC
1815 {
1816 bfd_set_section_size (abfd, tx, jmp_byte_count);
1579bae1 1817 td = xmalloc (jmp_byte_count);
775cabad
NC
1818 tx->contents = td;
1819 memcpy (td, jmp_bytes, jmp_byte_count);
1820
1821 switch (pe_details->pe_arch)
1822 {
1823 case PE_ARCH_i386:
1824 quick_reloc (abfd, 2, BFD_RELOC_32, 2);
1825 break;
1826 case PE_ARCH_sh:
1827 quick_reloc (abfd, 8, BFD_RELOC_32, 2);
1828 break;
1829 case PE_ARCH_mips:
1830 quick_reloc (abfd, 0, BFD_RELOC_HI16_S, 2);
1831 quick_reloc (abfd, 0, BFD_RELOC_LO16, 0); /* MIPS_R_PAIR */
1832 quick_reloc (abfd, 4, BFD_RELOC_LO16, 2);
1833 break;
1834 default:
1835 abort ();
1836 }
1837 save_relocs (tx);
1838 }
252b5132
RH
1839
1840 bfd_set_section_size (abfd, id7, 4);
1579bae1 1841 d7 = xmalloc (4);
252b5132
RH
1842 id7->contents = d7;
1843 memset (d7, 0, 4);
4b7f0676 1844 quick_reloc (abfd, 0, BFD_RELOC_RVA, 5);
252b5132
RH
1845 save_relocs (id7);
1846
1847 bfd_set_section_size (abfd, id5, 4);
1579bae1 1848 d5 = xmalloc (4);
252b5132
RH
1849 id5->contents = d5;
1850 memset (d5, 0, 4);
775cabad 1851
252b5132
RH
1852 if (exp->flag_noname)
1853 {
1854 d5[0] = exp->ordinal;
1855 d5[1] = exp->ordinal >> 8;
1856 d5[3] = 0x80;
1857 }
1858 else
1859 {
1860 quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
1861 save_relocs (id5);
1862 }
1863
1864 bfd_set_section_size (abfd, id4, 4);
1579bae1 1865 d4 = xmalloc (4);
252b5132
RH
1866 id4->contents = d4;
1867 memset (d4, 0, 4);
775cabad 1868
252b5132
RH
1869 if (exp->flag_noname)
1870 {
c2a94a7a
DD
1871 d4[0] = exp->ordinal;
1872 d4[1] = exp->ordinal >> 8;
1873 d4[3] = 0x80;
252b5132
RH
1874 }
1875 else
1876 {
1877 quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
1878 save_relocs (id4);
1879 }
1880
1881 if (exp->flag_noname)
1882 {
1883 len = 0;
1884 bfd_set_section_size (abfd, id6, 0);
1885 }
1886 else
1887 {
1888 len = strlen (exp->name) + 3;
1889 if (len & 1)
1890 len++;
1891 bfd_set_section_size (abfd, id6, len);
1579bae1 1892 d6 = xmalloc (len);
252b5132
RH
1893 id6->contents = d6;
1894 memset (d6, 0, len);
1895 d6[0] = exp->hint & 0xff;
1896 d6[1] = exp->hint >> 8;
47639182 1897 strcpy ((char *) d6 + 2, exp->name);
252b5132
RH
1898 }
1899
1900 bfd_set_symtab (abfd, symtab, symptr);
1901
c6c37250 1902 bfd_set_section_contents (abfd, tx, td, 0, jmp_byte_count);
252b5132
RH
1903 bfd_set_section_contents (abfd, id7, d7, 0, 4);
1904 bfd_set_section_contents (abfd, id5, d5, 0, 4);
1905 bfd_set_section_contents (abfd, id4, d4, 0, 4);
1906 if (!exp->flag_noname)
1907 bfd_set_section_contents (abfd, id6, d6, 0, len);
1908
1909 bfd_make_readable (abfd);
1910 return abfd;
1911}
1912
b044cda1 1913static bfd *
1579bae1 1914make_singleton_name_thunk (const char *import, bfd *parent)
b044cda1 1915{
775cabad 1916 /* Name thunks go to idata$4. */
b044cda1
CW
1917 asection *id4;
1918 unsigned char *d4;
1919 char *oname;
1920 bfd *abfd;
1921
1579bae1 1922 oname = xmalloc (20);
b044cda1
CW
1923 sprintf (oname, "nmth%06d.o", tmp_seq);
1924 tmp_seq++;
1925
1926 abfd = bfd_create (oname, parent);
1927 bfd_find_target (pe_details->object_target, abfd);
1928 bfd_make_writable (abfd);
1929
1930 bfd_set_format (abfd, bfd_object);
1931 bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
1932
1933 symptr = 0;
1579bae1 1934 symtab = xmalloc (3 * sizeof (asymbol *));
b044cda1
CW
1935 id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
1936 quick_symbol (abfd, U ("_nm_thnk_"), import, "", id4, BSF_GLOBAL, 0);
1937 quick_symbol (abfd, U ("_nm_"), import, "", UNDSEC, BSF_GLOBAL, 0);
1938
1939 bfd_set_section_size (abfd, id4, 8);
1579bae1 1940 d4 = xmalloc (4);
b044cda1
CW
1941 id4->contents = d4;
1942 memset (d4, 0, 8);
1943 quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
1944 save_relocs (id4);
1945
1946 bfd_set_symtab (abfd, symtab, symptr);
1947
1948 bfd_set_section_contents (abfd, id4, d4, 0, 8);
1949
1950 bfd_make_readable (abfd);
1951 return abfd;
1952}
1953
1954static char *
1579bae1 1955make_import_fixup_mark (arelent *rel)
b044cda1 1956{
775cabad 1957 /* We convert reloc to symbol, for later reference. */
b044cda1
CW
1958 static int counter;
1959 static char *fixup_name = NULL;
db09f25b 1960 static size_t buffer_len = 0;
b7a26f91 1961
fc0a2244 1962 struct bfd_symbol *sym = *rel->sym_ptr_ptr;
b7a26f91 1963
b044cda1 1964 bfd *abfd = bfd_asymbol_bfd (sym);
fe213ce2 1965 struct bfd_link_hash_entry *bh;
b044cda1
CW
1966
1967 if (!fixup_name)
1968 {
1579bae1 1969 fixup_name = xmalloc (384);
b044cda1
CW
1970 buffer_len = 384;
1971 }
1972
1973 if (strlen (sym->name) + 25 > buffer_len)
b7a26f91 1974 /* Assume 25 chars for "__fu" + counter + "_". If counter is
b044cda1 1975 bigger than 20 digits long, we've got worse problems than
775cabad 1976 overflowing this buffer... */
b044cda1
CW
1977 {
1978 free (fixup_name);
a35bc64f
NC
1979 /* New buffer size is length of symbol, plus 25, but
1980 then rounded up to the nearest multiple of 128. */
b044cda1 1981 buffer_len = ((strlen (sym->name) + 25) + 127) & ~127;
1579bae1 1982 fixup_name = xmalloc (buffer_len);
b044cda1 1983 }
b7a26f91 1984
b044cda1
CW
1985 sprintf (fixup_name, "__fu%d_%s", counter++, sym->name);
1986
fe213ce2 1987 bh = NULL;
b7a26f91 1988 bfd_coff_link_add_one_symbol (&link_info, abfd, fixup_name, BSF_GLOBAL,
b044cda1 1989 current_sec, /* sym->section, */
b34976b6 1990 rel->address, NULL, TRUE, FALSE, &bh);
fe213ce2
AM
1991
1992 if (0)
1993 {
1994 struct coff_link_hash_entry *myh;
1995
1996 myh = (struct coff_link_hash_entry *) bh;
1997 printf ("type:%d\n", myh->type);
1998 printf ("%s\n", myh->root.u.def.section->name);
1999 }
b044cda1 2000
b044cda1
CW
2001 return fixup_name;
2002}
2003
775cabad
NC
2004/* .section .idata$3
2005 .rva __nm_thnk_SYM (singleton thunk with name of func)
2006 .long 0
2007 .long 0
2008 .rva __my_dll_iname (name of dll)
2009 .rva __fuNN_SYM (pointer to reference (address) in text) */
b044cda1
CW
2010
2011static bfd *
1579bae1
AM
2012make_import_fixup_entry (const char *name,
2013 const char *fixup_name,
2014 const char *dll_symname,
2015 bfd *parent)
b044cda1
CW
2016{
2017 asection *id3;
2018 unsigned char *d3;
2019 char *oname;
2020 bfd *abfd;
2021
1579bae1 2022 oname = xmalloc (20);
b044cda1
CW
2023 sprintf (oname, "fu%06d.o", tmp_seq);
2024 tmp_seq++;
2025
2026 abfd = bfd_create (oname, parent);
2027 bfd_find_target (pe_details->object_target, abfd);
2028 bfd_make_writable (abfd);
2029
2030 bfd_set_format (abfd, bfd_object);
2031 bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
2032
2033 symptr = 0;
1579bae1 2034 symtab = xmalloc (6 * sizeof (asymbol *));
b044cda1 2035 id3 = quick_section (abfd, ".idata$3", SEC_HAS_CONTENTS, 2);
775cabad 2036
b044cda1
CW
2037 quick_symbol (abfd, U ("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0);
2038 quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
2039 quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
2040
2041 bfd_set_section_size (abfd, id3, 20);
1579bae1 2042 d3 = xmalloc (20);
b044cda1
CW
2043 id3->contents = d3;
2044 memset (d3, 0, 20);
2045
2046 quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
2047 quick_reloc (abfd, 12, BFD_RELOC_RVA, 2);
2048 quick_reloc (abfd, 16, BFD_RELOC_RVA, 3);
2049 save_relocs (id3);
2050
2051 bfd_set_symtab (abfd, symtab, symptr);
2052
2053 bfd_set_section_contents (abfd, id3, d3, 0, 20);
2054
2055 bfd_make_readable (abfd);
2056 return abfd;
2057}
2058
2fa9fc65
NC
2059/* .section .rdata_runtime_pseudo_reloc
2060 .long addend
2061 .rva __fuNN_SYM (pointer to reference (address) in text) */
2062
2063static bfd *
1579bae1
AM
2064make_runtime_pseudo_reloc (const char *name ATTRIBUTE_UNUSED,
2065 const char *fixup_name,
2066 int addend,
2067 bfd *parent)
2fa9fc65
NC
2068{
2069 asection *rt_rel;
2070 unsigned char *rt_rel_d;
2071 char *oname;
2072 bfd *abfd;
2073
1579bae1 2074 oname = xmalloc (20);
2fa9fc65
NC
2075 sprintf (oname, "rtr%06d.o", tmp_seq);
2076 tmp_seq++;
2077
2078 abfd = bfd_create (oname, parent);
2079 bfd_find_target (pe_details->object_target, abfd);
2080 bfd_make_writable (abfd);
2081
2082 bfd_set_format (abfd, bfd_object);
2083 bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
2084
2085 symptr = 0;
1579bae1
AM
2086 symtab = xmalloc (2 * sizeof (asymbol *));
2087 rt_rel = quick_section (abfd, ".rdata_runtime_pseudo_reloc",
2088 SEC_HAS_CONTENTS, 2);
2fa9fc65
NC
2089
2090 quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
2091
2092 bfd_set_section_size (abfd, rt_rel, 8);
1579bae1 2093 rt_rel_d = xmalloc (8);
2fa9fc65
NC
2094 rt_rel->contents = rt_rel_d;
2095 memset (rt_rel_d, 0, 8);
2096 bfd_put_32 (abfd, addend, rt_rel_d);
2097
2098 quick_reloc (abfd, 4, BFD_RELOC_RVA, 1);
2099 save_relocs (rt_rel);
2100
2101 bfd_set_symtab (abfd, symtab, symptr);
2102
2103 bfd_set_section_contents (abfd, rt_rel, rt_rel_d, 0, 8);
2104
2105 bfd_make_readable (abfd);
2106 return abfd;
2107}
2108
2109/* .section .rdata
a35bc64f 2110 .rva __pei386_runtime_relocator */
2fa9fc65
NC
2111
2112static bfd *
1579bae1 2113pe_create_runtime_relocator_reference (bfd *parent)
2fa9fc65
NC
2114{
2115 asection *extern_rt_rel;
2116 unsigned char *extern_rt_rel_d;
2117 char *oname;
2118 bfd *abfd;
2119
1579bae1 2120 oname = xmalloc (20);
2fa9fc65
NC
2121 sprintf (oname, "ertr%06d.o", tmp_seq);
2122 tmp_seq++;
2123
2124 abfd = bfd_create (oname, parent);
2125 bfd_find_target (pe_details->object_target, abfd);
2126 bfd_make_writable (abfd);
2127
2128 bfd_set_format (abfd, bfd_object);
2129 bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
2130
2131 symptr = 0;
1579bae1 2132 symtab = xmalloc (2 * sizeof (asymbol *));
2fa9fc65
NC
2133 extern_rt_rel = quick_section (abfd, ".rdata", SEC_HAS_CONTENTS, 2);
2134
1579bae1
AM
2135 quick_symbol (abfd, "", "__pei386_runtime_relocator", "", UNDSEC,
2136 BSF_NO_FLAGS, 0);
2fa9fc65
NC
2137
2138 bfd_set_section_size (abfd, extern_rt_rel, 4);
1579bae1 2139 extern_rt_rel_d = xmalloc (4);
2fa9fc65
NC
2140 extern_rt_rel->contents = extern_rt_rel_d;
2141
2142 quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
2143 save_relocs (extern_rt_rel);
2144
2145 bfd_set_symtab (abfd, symtab, symptr);
2146
2147 bfd_set_section_contents (abfd, extern_rt_rel, extern_rt_rel_d, 0, 4);
2148
2149 bfd_make_readable (abfd);
2150 return abfd;
2151}
2152
b044cda1 2153void
1579bae1 2154pe_create_import_fixup (arelent *rel, asection *s, int addend)
b044cda1
CW
2155{
2156 char buf[300];
fc0a2244 2157 struct bfd_symbol *sym = *rel->sym_ptr_ptr;
b044cda1 2158 struct bfd_link_hash_entry *name_thunk_sym;
db09f25b 2159 const char *name = sym->name;
b044cda1 2160 char *fixup_name = make_import_fixup_mark (rel);
2fa9fc65 2161 bfd *b;
b044cda1
CW
2162
2163 sprintf (buf, U ("_nm_thnk_%s"), name);
2164
2165 name_thunk_sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
2166
2167 if (!name_thunk_sym || name_thunk_sym->type != bfd_link_hash_defined)
2168 {
2169 bfd *b = make_singleton_name_thunk (name, output_bfd);
2170 add_bfd_to_link (b, b->filename, &link_info);
2171
775cabad 2172 /* If we ever use autoimport, we have to cast text section writable. */
b34976b6 2173 config.text_read_only = FALSE;
4d8907ac 2174 output_bfd->flags &= ~WP_TEXT;
b044cda1
CW
2175 }
2176
2fa9fc65
NC
2177 if (addend == 0 || link_info.pei386_runtime_pseudo_reloc)
2178 {
2179 extern char * pe_data_import_dll;
2180 char * dll_symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
aa3d9aba 2181
2fa9fc65
NC
2182 b = make_import_fixup_entry (name, fixup_name, dll_symname, output_bfd);
2183 add_bfd_to_link (b, b->filename, &link_info);
2184 }
2185
2186 if (addend != 0)
2187 {
2188 if (link_info.pei386_runtime_pseudo_reloc)
2189 {
2190 if (pe_dll_extra_pe_debug)
2191 printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
2192 fixup_name, addend);
2193 b = make_runtime_pseudo_reloc (name, fixup_name, addend, output_bfd);
2194 add_bfd_to_link (b, b->filename, &link_info);
2195
2196 if (runtime_pseudo_relocs_created == 0)
2197 {
2198 b = pe_create_runtime_relocator_reference (output_bfd);
2199 add_bfd_to_link (b, b->filename, &link_info);
2200 }
2201 runtime_pseudo_relocs_created++;
b34976b6 2202 }
2fa9fc65
NC
2203 else
2204 {
2205 einfo (_("%C: variable '%T' can't be auto-imported. Please read the documentation for ld's --enable-auto-import for details.\n"),
2206 s->owner, s, rel->address, sym->name);
2207 einfo ("%X");
2208 }
2209 }
b044cda1
CW
2210}
2211
2212
252b5132 2213void
1579bae1 2214pe_dll_generate_implib (def_file *def, const char *impfilename)
252b5132
RH
2215{
2216 int i;
2217 bfd *ar_head;
2218 bfd *ar_tail;
2219 bfd *outarch;
2220 bfd *head = 0;
2221
5aaace27 2222 dll_filename = (def->name) ? def->name : dll_name;
252b5132 2223 dll_symname = xstrdup (dll_filename);
d643799d 2224 for (i = 0; dll_symname[i]; i++)
3882b010 2225 if (!ISALNUM (dll_symname[i]))
252b5132
RH
2226 dll_symname[i] = '_';
2227
2228 unlink (impfilename);
2229
2230 outarch = bfd_openw (impfilename, 0);
2231
2232 if (!outarch)
2233 {
2234 /* xgettext:c-format */
2235 einfo (_("%XCan't open .lib file: %s\n"), impfilename);
2236 return;
2237 }
2238
2239 /* xgettext:c-format */
2240 einfo (_("Creating library file: %s\n"), impfilename);
5cc18311 2241
252b5132
RH
2242 bfd_set_format (outarch, bfd_archive);
2243 outarch->has_armap = 1;
2244
5cc18311 2245 /* Work out a reasonable size of things to put onto one line. */
252b5132 2246 ar_head = make_head (outarch);
252b5132 2247
d643799d 2248 for (i = 0; i < def->num_exports; i++)
252b5132 2249 {
86b1cc60 2250 /* The import library doesn't know about the internal name. */
252b5132
RH
2251 char *internal = def->exports[i].internal_name;
2252 bfd *n;
775cabad 2253
ee31fbd0
NC
2254 /* Don't add PRIVATE entries to import lib. */
2255 if (pe_def_file->exports[i].flag_private)
2256 continue;
252b5132 2257 def->exports[i].internal_name = def->exports[i].name;
d643799d 2258 n = make_one (def->exports + i, outarch);
252b5132
RH
2259 n->next = head;
2260 head = n;
2261 def->exports[i].internal_name = internal;
2262 }
2263
c6c37250
DD
2264 ar_tail = make_tail (outarch);
2265
2266 if (ar_head == NULL || ar_tail == NULL)
2267 return;
2268
86b1cc60 2269 /* Now stick them all into the archive. */
252b5132
RH
2270 ar_head->next = head;
2271 ar_tail->next = ar_head;
2272 head = ar_tail;
2273
2274 if (! bfd_set_archive_head (outarch, head))
2275 einfo ("%Xbfd_set_archive_head: %s\n", bfd_errmsg (bfd_get_error ()));
5cc18311 2276
252b5132
RH
2277 if (! bfd_close (outarch))
2278 einfo ("%Xbfd_close %s: %s\n", impfilename, bfd_errmsg (bfd_get_error ()));
2279
2280 while (head != NULL)
2281 {
2282 bfd *n = head->next;
2283 bfd_close (head);
2284 head = n;
2285 }
2286}
2287
2288static void
1579bae1 2289add_bfd_to_link (bfd *abfd, const char *name, struct bfd_link_info *link_info)
252b5132
RH
2290{
2291 lang_input_statement_type *fake_file;
775cabad 2292
252b5132
RH
2293 fake_file = lang_add_input_file (name,
2294 lang_input_file_is_fake_enum,
2295 NULL);
2296 fake_file->the_bfd = abfd;
2297 ldlang_add_file (fake_file);
775cabad 2298
252b5132
RH
2299 if (!bfd_link_add_symbols (abfd, link_info))
2300 einfo ("%Xaddsym %s: %s\n", name, bfd_errmsg (bfd_get_error ()));
2301}
2302
2303void
1579bae1 2304pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info)
252b5132
RH
2305{
2306 def_file_module *module;
775cabad 2307
d643799d 2308 pe_dll_id_target (bfd_get_target (output_bfd));
252b5132
RH
2309
2310 if (!pe_def_file)
2311 return;
2312
2313 for (module = pe_def_file->modules; module; module = module->next)
2314 {
2315 int i, do_this_dll;
2316
2317 dll_filename = module->name;
2318 dll_symname = xstrdup (module->name);
d643799d 2319 for (i = 0; dll_symname[i]; i++)
3882b010 2320 if (!ISALNUM (dll_symname[i]))
252b5132
RH
2321 dll_symname[i] = '_';
2322
2323 do_this_dll = 0;
2324
d643799d 2325 for (i = 0; i < pe_def_file->num_imports; i++)
252b5132
RH
2326 if (pe_def_file->imports[i].module == module)
2327 {
2328 def_file_export exp;
2329 struct bfd_link_hash_entry *blhe;
b34976b6 2330 int lead_at = (*pe_def_file->imports[i].internal_name == '@');
86b1cc60 2331 /* See if we need this import. */
1579bae1
AM
2332 size_t len = strlen (pe_def_file->imports[i].internal_name);
2333 char *name = xmalloc (len + 2 + 6);
c9e38879
NC
2334
2335 if (lead_at)
1579bae1
AM
2336 sprintf (name, "%s%s", "",
2337 pe_def_file->imports[i].internal_name);
c9e38879 2338 else
1579bae1
AM
2339 sprintf (name, "%s%s",U (""),
2340 pe_def_file->imports[i].internal_name);
c9e38879 2341
252b5132 2342 blhe = bfd_link_hash_lookup (link_info->hash, name,
b34976b6 2343 FALSE, FALSE, FALSE);
c9e38879 2344
874c8c99
DD
2345 if (!blhe || (blhe && blhe->type != bfd_link_hash_undefined))
2346 {
c9e38879
NC
2347 if (lead_at)
2348 sprintf (name, "%s%s", U ("_imp_"),
2349 pe_def_file->imports[i].internal_name);
2350 else
2351 sprintf (name, "%s%s", U ("_imp__"),
2352 pe_def_file->imports[i].internal_name);
2353
874c8c99 2354 blhe = bfd_link_hash_lookup (link_info->hash, name,
b34976b6 2355 FALSE, FALSE, FALSE);
874c8c99 2356 }
252b5132 2357 free (name);
c9e38879 2358
252b5132
RH
2359 if (blhe && blhe->type == bfd_link_hash_undefined)
2360 {
2361 bfd *one;
86b1cc60 2362 /* We do. */
252b5132
RH
2363 if (!do_this_dll)
2364 {
2365 bfd *ar_head = make_head (output_bfd);
2366 add_bfd_to_link (ar_head, ar_head->filename, link_info);
2367 do_this_dll = 1;
2368 }
2369 exp.internal_name = pe_def_file->imports[i].internal_name;
2370 exp.name = pe_def_file->imports[i].name;
2371 exp.ordinal = pe_def_file->imports[i].ordinal;
2372 exp.hint = exp.ordinal >= 0 ? exp.ordinal : 0;
2373 exp.flag_private = 0;
2374 exp.flag_constant = 0;
939ba9d0 2375 exp.flag_data = pe_def_file->imports[i].data;
252b5132
RH
2376 exp.flag_noname = exp.name ? 0 : 1;
2377 one = make_one (&exp, output_bfd);
2378 add_bfd_to_link (one, one->filename, link_info);
2379 }
2380 }
2381 if (do_this_dll)
2382 {
2383 bfd *ar_tail = make_tail (output_bfd);
2384 add_bfd_to_link (ar_tail, ar_tail->filename, link_info);
2385 }
2386
2387 free (dll_symname);
2388 }
2389}
2390
775cabad 2391/* We were handed a *.DLL file. Parse it and turn it into a set of
b34976b6
AM
2392 IMPORTS directives in the def file. Return TRUE if the file was
2393 handled, FALSE if not. */
252b5132
RH
2394
2395static unsigned int
1579bae1 2396pe_get16 (bfd *abfd, int where)
252b5132
RH
2397{
2398 unsigned char b[2];
775cabad 2399
db09f25b
AM
2400 bfd_seek (abfd, (file_ptr) where, SEEK_SET);
2401 bfd_bread (b, (bfd_size_type) 2, abfd);
d643799d 2402 return b[0] + (b[1] << 8);
252b5132
RH
2403}
2404
2405static unsigned int
1579bae1 2406pe_get32 (bfd *abfd, int where)
252b5132
RH
2407{
2408 unsigned char b[4];
775cabad 2409
db09f25b
AM
2410 bfd_seek (abfd, (file_ptr) where, SEEK_SET);
2411 bfd_bread (b, (bfd_size_type) 4, abfd);
d643799d 2412 return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
252b5132
RH
2413}
2414
252b5132 2415static unsigned int
1579bae1 2416pe_as32 (void *ptr)
252b5132
RH
2417{
2418 unsigned char *b = ptr;
775cabad 2419
d643799d 2420 return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
252b5132
RH
2421}
2422
b34976b6 2423bfd_boolean
1579bae1 2424pe_implied_import_dll (const char *filename)
252b5132
RH
2425{
2426 bfd *dll;
2427 unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
2428 unsigned long export_rva, export_size, nsections, secptr, expptr;
939ba9d0 2429 unsigned long exp_funcbase;
47639182
AM
2430 unsigned char *expdata;
2431 char *erva;
252b5132 2432 unsigned long name_rvas, ordinals, nexp, ordbase;
1069dd8d 2433 const char *dll_name;
939ba9d0
NC
2434 /* Initialization with start > end guarantees that is_data
2435 will not be set by mistake, and avoids compiler warning. */
2436 unsigned long data_start = 1;
661a32f7
DS
2437 unsigned long data_end = 0;
2438 unsigned long rdata_start = 1;
2439 unsigned long rdata_end = 0;
2440 unsigned long bss_start = 1;
2441 unsigned long bss_end = 0;
252b5132
RH
2442
2443 /* No, I can't use bfd here. kernel32.dll puts its export table in
5cc18311 2444 the middle of the .rdata section. */
c6c37250 2445 dll = bfd_openr (filename, pe_details->target_name);
252b5132
RH
2446 if (!dll)
2447 {
2448 einfo ("%Xopen %s: %s\n", filename, bfd_errmsg (bfd_get_error ()));
b34976b6 2449 return FALSE;
252b5132 2450 }
775cabad 2451
86b1cc60 2452 /* PEI dlls seem to be bfd_objects. */
252b5132
RH
2453 if (!bfd_check_format (dll, bfd_object))
2454 {
2455 einfo ("%X%s: this doesn't appear to be a DLL\n", filename);
b34976b6 2456 return FALSE;
252b5132
RH
2457 }
2458
939ba9d0 2459 /* Get pe_header, optional header and numbers of export entries. */
252b5132
RH
2460 pe_header_offset = pe_get32 (dll, 0x3c);
2461 opthdr_ofs = pe_header_offset + 4 + 20;
2462 num_entries = pe_get32 (dll, opthdr_ofs + 92);
775cabad
NC
2463
2464 if (num_entries < 1) /* No exports. */
b34976b6 2465 return FALSE;
775cabad 2466
252b5132
RH
2467 export_rva = pe_get32 (dll, opthdr_ofs + 96);
2468 export_size = pe_get32 (dll, opthdr_ofs + 100);
2469 nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
2470 secptr = (pe_header_offset + 4 + 20 +
2471 pe_get16 (dll, pe_header_offset + 4 + 16));
2472 expptr = 0;
775cabad 2473
1579bae1 2474 /* Get the rva and size of the export section. */
d643799d 2475 for (i = 0; i < nsections; i++)
252b5132
RH
2476 {
2477 char sname[8];
2478 unsigned long secptr1 = secptr + 40 * i;
2479 unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
2480 unsigned long vsize = pe_get32 (dll, secptr1 + 16);
2481 unsigned long fptr = pe_get32 (dll, secptr1 + 20);
775cabad 2482
db09f25b
AM
2483 bfd_seek (dll, (file_ptr) secptr1, SEEK_SET);
2484 bfd_bread (sname, (bfd_size_type) 8, dll);
775cabad 2485
d643799d 2486 if (vaddr <= export_rva && vaddr + vsize > export_rva)
252b5132
RH
2487 {
2488 expptr = fptr + (export_rva - vaddr);
2489 if (export_rva + export_size > vaddr + vsize)
2490 export_size = vsize - (export_rva - vaddr);
2491 break;
2492 }
2493 }
2494
939ba9d0 2495 /* Scan sections and store the base and size of the
1579bae1 2496 data and bss segments in data/base_start/end. */
939ba9d0
NC
2497 for (i = 0; i < nsections; i++)
2498 {
2499 unsigned long secptr1 = secptr + 40 * i;
2500 unsigned long vsize = pe_get32 (dll, secptr1 + 8);
2501 unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
2502 unsigned long flags = pe_get32 (dll, secptr1 + 36);
2503 char sec_name[9];
2504
2505 sec_name[8] = '\0';
2506 bfd_seek (dll, (file_ptr) secptr1 + 0, SEEK_SET);
2507 bfd_bread (sec_name, (bfd_size_type) 8, dll);
2508
2509 if (strcmp(sec_name,".data") == 0)
2510 {
2511 data_start = vaddr;
2512 data_end = vaddr + vsize;
2513
661a32f7
DS
2514 if (pe_dll_extra_pe_debug)
2515 printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
2516 __FUNCTION__, sec_name, vaddr, vaddr + vsize, flags);
2517 }
2518 else if (strcmp(sec_name,".rdata") == 0)
2519 {
2520 rdata_start = vaddr;
2521 rdata_end = vaddr + vsize;
2522
939ba9d0
NC
2523 if (pe_dll_extra_pe_debug)
2524 printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
2525 __FUNCTION__, sec_name, vaddr, vaddr + vsize, flags);
1579bae1 2526 }
939ba9d0
NC
2527 else if (strcmp (sec_name,".bss") == 0)
2528 {
2529 bss_start = vaddr;
2530 bss_end = vaddr + vsize;
2531
2532 if (pe_dll_extra_pe_debug)
2533 printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
2534 __FUNCTION__, sec_name, vaddr, vaddr + vsize, flags);
2535 }
2536 }
2537
1579bae1 2538 expdata = xmalloc (export_size);
db09f25b
AM
2539 bfd_seek (dll, (file_ptr) expptr, SEEK_SET);
2540 bfd_bread (expdata, (bfd_size_type) export_size, dll);
47639182 2541 erva = (char *) expdata - export_rva;
252b5132
RH
2542
2543 if (pe_def_file == 0)
d643799d 2544 pe_def_file = def_file_empty ();
252b5132 2545
d643799d
KH
2546 nexp = pe_as32 (expdata + 24);
2547 name_rvas = pe_as32 (expdata + 32);
2548 ordinals = pe_as32 (expdata + 36);
2549 ordbase = pe_as32 (expdata + 16);
939ba9d0 2550 exp_funcbase = pe_as32 (expdata + 28);
775cabad 2551
939ba9d0
NC
2552 /* Use internal dll name instead of filename
2553 to enable symbolic dll linking. */
47639182 2554 dll_name = erva + pe_as32 (expdata + 12);
939ba9d0 2555
a35bc64f
NC
2556 /* Check to see if the dll has already been added to
2557 the definition list and if so return without error.
2558 This avoids multiple symbol definitions. */
2559 if (def_get_module (pe_def_file, dll_name))
2560 {
2561 if (pe_dll_extra_pe_debug)
2562 printf ("%s is already loaded\n", dll_name);
2563 return TRUE;
2564 }
2565
939ba9d0 2566 /* Iterate through the list of symbols. */
d643799d 2567 for (i = 0; i < nexp; i++)
252b5132 2568 {
939ba9d0 2569 /* Pointer to the names vector. */
d643799d 2570 unsigned long name_rva = pe_as32 (erva + name_rvas + i * 4);
252b5132 2571 def_file_import *imp;
1579bae1 2572 /* Pointer to the function address vector. */
939ba9d0
NC
2573 unsigned long func_rva = pe_as32 (erva + exp_funcbase + i * 4);
2574 int is_data = 0;
2575
2576 /* Skip unwanted symbols, which are
2577 exported in buggy auto-import releases. */
2578 if (strncmp (erva + name_rva, "_nm_", 4) != 0)
2579 {
661a32f7
DS
2580 /* is_data is true if the address is in the data, rdata or bss
2581 segment. */
939ba9d0
NC
2582 is_data =
2583 (func_rva >= data_start && func_rva < data_end)
661a32f7 2584 || (func_rva >= rdata_start && func_rva < rdata_end)
939ba9d0
NC
2585 || (func_rva >= bss_start && func_rva < bss_end);
2586
2587 imp = def_file_add_import (pe_def_file, erva + name_rva,
2588 dll_name, i, 0);
396a2467 2589 /* Mark symbol type. */
939ba9d0 2590 imp->data = is_data;
1579bae1 2591
939ba9d0
NC
2592 if (pe_dll_extra_pe_debug)
2593 printf ("%s dll-name: %s sym: %s addr: 0x%lx %s\n",
2594 __FUNCTION__, dll_name, erva + name_rva,
2595 func_rva, is_data ? "(data)" : "");
2596 }
252b5132
RH
2597 }
2598
b34976b6 2599 return TRUE;
252b5132
RH
2600}
2601
775cabad
NC
2602/* These are the main functions, called from the emulation. The first
2603 is called after the bfds are read, so we can guess at how much space
2604 we need. The second is called after everything is placed, so we
2605 can put the right values in place. */
252b5132
RH
2606
2607void
1579bae1 2608pe_dll_build_sections (bfd *abfd, struct bfd_link_info *info)
252b5132 2609{
c6c37250 2610 pe_dll_id_target (bfd_get_target (abfd));
252b5132
RH
2611 process_def_file (abfd, info);
2612
1579bae1 2613 if (pe_def_file->num_exports == 0 && !info->shared)
2b817be1
NC
2614 return;
2615
252b5132 2616 generate_edata (abfd, info);
c6c37250
DD
2617 build_filler_bfd (1);
2618}
2619
2620void
1579bae1 2621pe_exe_build_sections (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
c6c37250
DD
2622{
2623 pe_dll_id_target (bfd_get_target (abfd));
2624 build_filler_bfd (0);
252b5132
RH
2625}
2626
2627void
1579bae1 2628pe_dll_fill_sections (bfd *abfd, struct bfd_link_info *info)
252b5132 2629{
c6c37250 2630 pe_dll_id_target (bfd_get_target (abfd));
252b5132
RH
2631 image_base = pe_data (abfd)->pe_opthdr.ImageBase;
2632
2633 generate_reloc (abfd, info);
2634 if (reloc_sz > 0)
2635 {
2636 bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
2637
2638 /* Resize the sections. */
2639 lang_size_sections (stat_ptr->head, abs_output_section,
1579bae1 2640 &stat_ptr->head, 0, 0, NULL, TRUE);
252b5132
RH
2641
2642 /* Redo special stuff. */
2643 ldemul_after_allocation ();
2644
2645 /* Do the assignments again. */
1579bae1 2646 lang_do_assignments (stat_ptr->head, abs_output_section, NULL, 0);
252b5132
RH
2647 }
2648
2649 fill_edata (abfd, info);
2650
db8acf26 2651 if (info->shared && !info->pie)
2b817be1 2652 pe_data (abfd)->dll = 1;
252b5132
RH
2653
2654 edata_s->contents = edata_d;
2655 reloc_s->contents = reloc_d;
2656}
c6c37250
DD
2657
2658void
1579bae1 2659pe_exe_fill_sections (bfd *abfd, struct bfd_link_info *info)
c6c37250
DD
2660{
2661 pe_dll_id_target (bfd_get_target (abfd));
2662 image_base = pe_data (abfd)->pe_opthdr.ImageBase;
2663
2664 generate_reloc (abfd, info);
2665 if (reloc_sz > 0)
2666 {
2667 bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
2668
2669 /* Resize the sections. */
2670 lang_size_sections (stat_ptr->head, abs_output_section,
1579bae1 2671 &stat_ptr->head, 0, 0, NULL, TRUE);
c6c37250
DD
2672
2673 /* Redo special stuff. */
2674 ldemul_after_allocation ();
2675
2676 /* Do the assignments again. */
1579bae1 2677 lang_do_assignments (stat_ptr->head, abs_output_section, NULL, 0);
c6c37250
DD
2678 }
2679 reloc_s->contents = reloc_d;
2680}