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