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