Fix typo in orevious delta
[deliverable/binutils-gdb.git] / ld / pe-dll.c
CommitLineData
eb8061bf
DD
1/* Routines to help build PEI-format DLLs (Win32 etc)
2 Copyright (C) 1998 Free Software Foundation, Inc.
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"
26
27#include "ld.h"
28#include "ldexp.h"
29#include "ldlang.h"
30#include "ldwrite.h"
31#include "ldmisc.h"
32#include "ldgram.h"
33#include "ldmain.h"
34#include "coff/internal.h"
35#include "../bfd/libcoff.h"
36#include "deffile.h"
37
38/************************************************************************
39
40 This file turns a regular Windows PE image into a DLL. Because of
41 the complexity of this operation, it has been broken down into a
42 number of separate modules which are all called by the main function
43 at the end of this file. This function is not re-entrant and is
44 normally only called once, so static variables are used to reduce
45 the number of parameters and return values required.
46
47 See also: ld/emultempl/pe.em
48
49 ************************************************************************/
50
51/* from emultempl/pe.em */
52
53extern def_file *pe_def_file;
54extern int pe_dll_export_everything;
55extern int pe_dll_do_default_excludes;
56extern int pe_dll_kill_ats;
57extern int pe_dll_stdcall_aliases;
58
59/************************************************************************
60
61 static variables and types
62
63 ************************************************************************/
64
65static bfd_vma image_base;
66
67static bfd *filler_bfd;
68static struct sec *edata_s, *reloc_s;
69static unsigned char *edata_d, *reloc_d;
70static int edata_sz, reloc_sz;
71
72/************************************************************************
73
74 Helper functions for qsort. Relocs must be sorted so that we can write
75 them out by pages.
76
77 ************************************************************************/
78
79static int
80reloc_sort (va, vb)
81 const void *va, *vb;
82{
83 unsigned long a = *(unsigned long *) va;
84 unsigned long b = *(unsigned long *) vb;
85 return a - b;
86}
87
88static int
89pe_export_sort (va, vb)
90 const void *va, *vb;
91{
92 def_file_export *a = (def_file_export *) va;
93 def_file_export *b = (def_file_export *) vb;
94 return strcmp (a->name, b->name);
95}
96
97/************************************************************************
98
99 Read and process the .DEF file
100
101 ************************************************************************/
102
103/* These correspond to the entries in pe_def_file->exports[]. I use
104 exported_symbol_sections[i] to tag whether or not the symbol was
105 defined, since we can't export symbols we don't have. */
106
107static bfd_vma *exported_symbol_offsets;
108static struct sec **exported_symbol_sections;
109
110static int export_table_size;
111static int count_exported;
112static int count_exported_byname;
113static int count_with_ordinals;
114static const char *dll_name;
115static int min_ordinal, max_ordinal;
116static int *exported_symbols;
117
118typedef struct exclude_list_struct
119 {
120 char *string;
121 struct exclude_list_struct *next;
122 }
123exclude_list_struct;
124static struct exclude_list_struct *excludes = 0;
125
126void
127pe_dll_add_excludes (new_excludes)
128 const char *new_excludes;
129{
130 char *local_copy;
131 char *exclude_string;
132
133 local_copy = xstrdup (new_excludes);
134
135 exclude_string = strtok (local_copy, ",:");
136 for (; exclude_string; exclude_string = strtok (NULL, ",:"))
137 {
138 struct exclude_list_struct *new_exclude;
139
140 new_exclude = ((struct exclude_list_struct *)
141 xmalloc (sizeof (struct exclude_list_struct)));
142 new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 1);
143 strcpy (new_exclude->string, exclude_string);
144 new_exclude->next = excludes;
145 excludes = new_exclude;
146 }
147
148 free (local_copy);
149}
150
151static int
152auto_export (d, n)
153 def_file *d;
154 const char *n;
155{
156 int i;
157 struct exclude_list_struct *ex;
158 for (i = 0; i < d->num_exports; i++)
159 if (strcmp (d->exports[i].name, n) == 0)
160 return 0;
161 if (pe_dll_do_default_excludes)
162 {
163 if (strcmp (n, "DllMain@12") == 0)
164 return 0;
165 if (strcmp (n, "DllEntryPoint@0") == 0)
166 return 0;
167 if (strcmp (n, "impure_ptr") == 0)
168 return 0;
169 }
170 for (ex = excludes; ex; ex = ex->next)
171 if (strcmp (n, ex->string) == 0)
172 return 0;
173 return 1;
174}
175
176static void
177process_def_file (abfd, info)
178 bfd *abfd;
179 struct bfd_link_info *info;
180{
181 int i, j;
182 struct bfd_link_hash_entry *blhe;
183 bfd *b;
184 struct sec *s;
91c7ad9a 185 def_file_export *e=0;
eb8061bf
DD
186
187 if (!pe_def_file)
188 pe_def_file = def_file_empty ();
189
190 /* First, run around to all the objects looking for the .drectve
191 sections, and push those into the def file too */
192
193 for (b = info->input_bfds; b; b = b->link_next)
194 {
195 s = bfd_get_section_by_name (b, ".drectve");
196 if (s)
197 {
198 int size = bfd_get_section_size_before_reloc (s);
199 char *buf = xmalloc (size);
200 bfd_get_section_contents (b, s, buf, 0, size);
201 def_file_add_directive (pe_def_file, buf, size);
202 free (buf);
203 }
204 }
205
206 /* Now, maybe export everything else the default way */
207
69c4fd86 208 if (pe_dll_export_everything || pe_def_file->num_exports == 0)
eb8061bf
DD
209 {
210 for (b = info->input_bfds; b; b = b->link_next)
211 {
212 asymbol **symbols;
213 int nsyms, symsize;
214
215 symsize = bfd_get_symtab_upper_bound (b);
216 symbols = (asymbol **) xmalloc (symsize);
217 nsyms = bfd_canonicalize_symtab (b, symbols);
218
219 for (j = 0; j < nsyms; j++)
220 {
221 if ((symbols[j]->flags & (BSF_FUNCTION | BSF_GLOBAL))
222 == (BSF_FUNCTION | BSF_GLOBAL))
223 {
224 const char *sn = symbols[j]->name;
225 if (*sn == '_')
226 sn++;
227 if (auto_export (pe_def_file, sn))
228 def_file_add_export (pe_def_file, sn, 0, -1);
229 }
230 }
231 }
232 }
233
234#undef NE
235#define NE pe_def_file->num_exports
eb8061bf
DD
236
237 /* Canonicalize the export list */
238
239 if (pe_dll_kill_ats)
240 {
241 for (i = 0; i < NE; i++)
242 {
91c7ad9a 243 if (strchr (pe_def_file->exports[i].name, '@'))
eb8061bf
DD
244 {
245 /* This will preserve internal_name, which may have been pointing
246 to the same memory as name, or might not have */
91c7ad9a 247 char *tmp = xstrdup (pe_def_file->exports[i].name);
eb8061bf 248 *(strchr (tmp, '@')) = 0;
91c7ad9a 249 pe_def_file->exports[i].name = tmp;
eb8061bf
DD
250 }
251 }
252 }
253
254 if (pe_dll_stdcall_aliases)
255 {
256 for (i = 0; i < NE; i++)
257 {
91c7ad9a 258 if (strchr (pe_def_file->exports[i].name, '@'))
eb8061bf 259 {
91c7ad9a 260 char *tmp = xstrdup (pe_def_file->exports[i].name);
eb8061bf
DD
261 *(strchr (tmp, '@')) = 0;
262 if (auto_export (pe_def_file, tmp))
91c7ad9a
DD
263 def_file_add_export (pe_def_file, tmp,
264 pe_def_file->exports[i].internal_name, -1);
eb8061bf
DD
265 else
266 free (tmp);
267 }
268 }
269 }
270
a3606134 271 e = pe_def_file->exports; /* convenience, but watch out for it changing */
91c7ad9a 272
eb8061bf
DD
273 exported_symbol_offsets = (bfd_vma *) xmalloc (NE * sizeof (bfd_vma));
274 exported_symbol_sections = (struct sec **) xmalloc (NE * sizeof (struct sec *));
275
276 memset (exported_symbol_sections, 0, NE * sizeof (struct sec *));
277 max_ordinal = 0;
278 min_ordinal = 65536;
279 count_exported = 0;
280 count_exported_byname = 0;
281 count_with_ordinals = 0;
282
283 qsort (pe_def_file->exports, NE, sizeof (pe_def_file->exports[0]), pe_export_sort);
284 for (i = 0, j = 0; i < NE; i++)
285 {
286 if (i > 0 && strcmp (e[i].name, e[i - 1].name) == 0)
287 {
288 /* This is a duplicate */
289 if (e[j - 1].ordinal != -1
290 && e[i].ordinal != -1
291 && e[j - 1].ordinal != e[i].ordinal)
292 {
293 /* xgettext:c-format */
294 einfo (_("%XError, duplicate EXPORT with oridinals: %s (%d vs %d)\n"),
295 e[j - 1].name, e[j - 1].ordinal, e[i].ordinal);
296 }
297 else
298 {
299 /* xgettext:c-format */
300 einfo (_("Warning, duplicate EXPORT: %s\n"),
301 e[j - 1].name);
302 }
303 if (e[i].ordinal)
304 e[j - 1].ordinal = e[i].ordinal;
305 e[j - 1].flag_private |= e[i].flag_private;
306 e[j - 1].flag_constant |= e[i].flag_constant;
307 e[j - 1].flag_noname |= e[i].flag_noname;
308 e[j - 1].flag_data |= e[i].flag_data;
309 }
310 else
311 {
312 if (i != j)
313 e[j] = e[i];
314 j++;
315 }
316 }
317 pe_def_file->num_exports = j; /* == NE */
318
319 for (i = 0; i < NE; i++)
320 {
321 char *name = (char *) xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
322 *name = '_';
323 strcpy (name + 1, pe_def_file->exports[i].internal_name);
324
325 blhe = bfd_link_hash_lookup (info->hash,
326 name,
327 false, false, true);
328
329 if (blhe && (blhe->type == bfd_link_hash_defined))
330 {
331 count_exported++;
332 if (!pe_def_file->exports[i].flag_noname)
333 count_exported_byname++;
334 exported_symbol_offsets[i] = blhe->u.def.value;
335 exported_symbol_sections[i] = blhe->u.def.section;
336 if (pe_def_file->exports[i].ordinal != -1)
337 {
338 if (max_ordinal < pe_def_file->exports[i].ordinal)
339 max_ordinal = pe_def_file->exports[i].ordinal;
340 if (min_ordinal > pe_def_file->exports[i].ordinal)
341 min_ordinal = pe_def_file->exports[i].ordinal;
342 count_with_ordinals++;
343 }
344 }
e2586bc8 345 else if (blhe && blhe->type == bfd_link_hash_undefined)
eb8061bf
DD
346 {
347 /* xgettext:c-format */
e2586bc8 348 einfo (_("%XCannot export %s: symbol not defined\n"),
eb8061bf
DD
349 pe_def_file->exports[i].internal_name);
350 }
e2586bc8
DD
351 else if (blhe)
352 {
353 /* xgettext:c-format */
354 einfo (_("%XCannot export %s: symbol wrong type (%d vs %d)\n"),
355 pe_def_file->exports[i].internal_name,
356 blhe->type, bfd_link_hash_defined);
357 }
eb8061bf
DD
358 else
359 {
360 /* xgettext:c-format */
361 einfo (_("%XCannot export %s: symbol not found\n"),
362 pe_def_file->exports[i].internal_name);
363 }
3feaa5af 364 free (name);
eb8061bf 365 }
eb8061bf
DD
366}
367
368/************************************************************************
369
370 Build the bfd that will contain .edata and .reloc sections
371
372 ************************************************************************/
373
374static void
375build_filler_bfd ()
376{
3feaa5af 377 lang_input_statement_type *filler_file;
eb8061bf
DD
378 filler_file = lang_add_input_file ("dll stuff",
379 lang_input_file_is_fake_enum,
380 NULL);
381 filler_file->the_bfd = filler_bfd = bfd_create ("dll stuff", output_bfd);
382 if (filler_bfd == NULL
383 || !bfd_set_arch_mach (filler_bfd,
384 bfd_get_arch (output_bfd),
385 bfd_get_mach (output_bfd)))
386 {
387 einfo ("%X%P: can not create BFD %E\n");
388 return;
389 }
390
391 edata_s = bfd_make_section_old_way (filler_bfd, ".edata");
392 if (edata_s == NULL
393 || !bfd_set_section_flags (filler_bfd, edata_s,
394 (SEC_HAS_CONTENTS
395 | SEC_ALLOC
396 | SEC_LOAD
397 | SEC_KEEP
398 | SEC_IN_MEMORY)))
399 {
400 einfo ("%X%P: can not create .edata section: %E\n");
401 return;
402 }
403 bfd_set_section_size (filler_bfd, edata_s, edata_sz);
404
405 reloc_s = bfd_make_section_old_way (filler_bfd, ".reloc");
406 if (reloc_s == NULL
407 || !bfd_set_section_flags (filler_bfd, reloc_s,
408 (SEC_HAS_CONTENTS
409 | SEC_ALLOC
410 | SEC_LOAD
411 | SEC_KEEP
412 | SEC_IN_MEMORY)))
413 {
414 einfo ("%X%P: can not create .reloc section: %E\n");
415 return;
416 }
417 bfd_set_section_size (filler_bfd, reloc_s, 0);
418
419 ldlang_add_file (filler_file);
420}
421
422/************************************************************************
423
424 Gather all the exported symbols and build the .edata section
425
426 ************************************************************************/
427
428static void
429generate_edata (abfd, info)
430 bfd *abfd;
431 struct bfd_link_info *info;
432{
433 int i, j, next_ordinal;
434 int name_table_size = 0;
435 const char *dlnp;
436
437 /* First, we need to know how many exported symbols there are,
438 and what the range of ordinals is. */
439
440 if (pe_def_file->name)
441 {
442 dll_name = pe_def_file->name;
443 }
444 else
445 {
446 dll_name = abfd->filename;
447 for (dlnp = dll_name; *dlnp; dlnp++)
448 {
449 if (*dlnp == '\\' || *dlnp == '/' || *dlnp == ':')
450 dll_name = dlnp + 1;
451 }
452 }
453
454 if (count_with_ordinals && max_ordinal > count_exported)
455 {
456 if (min_ordinal > max_ordinal - count_exported + 1)
457 min_ordinal = max_ordinal - count_exported + 1;
458 }
459 else
460 {
461 min_ordinal = 1;
462 max_ordinal = count_exported;
463 }
464 export_table_size = max_ordinal - min_ordinal + 1;
465
466 exported_symbols = (int *) xmalloc (export_table_size * sizeof (int));
467 for (i = 0; i < export_table_size; i++)
468 exported_symbols[i] = -1;
469
470 /* Now we need to assign ordinals to those that don't have them */
471 for (i = 0; i < NE; i++)
472 {
473 if (exported_symbol_sections[i])
474 {
475 if (pe_def_file->exports[i].ordinal != -1)
476 {
477 int ei = pe_def_file->exports[i].ordinal - min_ordinal;
478 int pi = exported_symbols[ei];
479 if (pi != -1)
480 {
481 /* xgettext:c-format */
482 einfo (_("%XError, oridinal used twice: %d (%s vs %s)\n"),
483 pe_def_file->exports[i].ordinal,
484 pe_def_file->exports[i].name,
485 pe_def_file->exports[pi].name);
486 }
487 exported_symbols[ei] = i;
488 }
489 name_table_size += strlen (pe_def_file->exports[i].name) + 1;
490 }
491 }
492
493 next_ordinal = min_ordinal;
494 for (i = 0; i < NE; i++)
495 if (exported_symbol_sections[i])
496 if (pe_def_file->exports[i].ordinal == -1)
497 {
498 while (exported_symbols[next_ordinal - min_ordinal] != -1)
499 next_ordinal++;
500 exported_symbols[next_ordinal - min_ordinal] = i;
501 pe_def_file->exports[i].ordinal = next_ordinal;
502 }
503
504 /* OK, now we can allocate some memory */
505
506 edata_sz = (40 /* directory */
507 + 4 * export_table_size /* addresses */
508 + 4 * count_exported_byname /* name ptrs */
509 + 2 * count_exported_byname /* ordinals */
510 + name_table_size + strlen (dll_name) + 1);
511}
512
513static void
514fill_edata (abfd, info)
515 bfd *abfd;
516 struct bfd_link_info *info;
517{
d3ca9a53 518 int i, hint;
eb8061bf
DD
519 unsigned char *edirectory;
520 unsigned long *eaddresses;
521 unsigned long *enameptrs;
522 unsigned short *eordinals;
523 unsigned char *enamestr;
524
525 edata_d = (unsigned char *) xmalloc (edata_sz);
526
527 /* Note use of array pointer math here */
528 edirectory = edata_d;
529 eaddresses = (unsigned long *) (edata_d + 40);
530 enameptrs = eaddresses + export_table_size;
531 eordinals = (unsigned short *) (enameptrs + count_exported_byname);
532 enamestr = (char *) (eordinals + count_exported_byname);
533
534#define ERVA(ptr) (((unsigned char *)(ptr) - edata_d) + edata_s->output_section->vma - image_base)
535
536 memset (edata_d, 0, 40);
537 if (pe_def_file->version_major != -1)
538 {
539 bfd_put_16 (abfd, pe_def_file->version_major, edata_d + 8);
540 bfd_put_16 (abfd, pe_def_file->version_minor, edata_d + 10);
541 }
542 bfd_put_32 (abfd, ERVA (enamestr), edata_d + 12);
543 strcpy (enamestr, dll_name);
544 enamestr += strlen (enamestr) + 1;
545 bfd_put_32 (abfd, min_ordinal, edata_d + 16);
546 bfd_put_32 (abfd, export_table_size, edata_d + 20);
547 bfd_put_32 (abfd, count_exported_byname, edata_d + 24);
548 bfd_put_32 (abfd, ERVA (eaddresses), edata_d + 28);
549 bfd_put_32 (abfd, ERVA (enameptrs), edata_d + 32);
550 bfd_put_32 (abfd, ERVA (eordinals), edata_d + 36);
551
552 /* Ok, now for the filling in part */
d3ca9a53 553 hint = 0;
eb8061bf
DD
554 for (i = 0; i < export_table_size; i++)
555 {
556 int s = exported_symbols[i];
557 if (s != -1)
558 {
559 struct sec *ssec = exported_symbol_sections[s];
560 unsigned long srva = (exported_symbol_offsets[s]
561 + ssec->output_section->vma
562 + ssec->output_offset);
563
564 bfd_put_32 (abfd, srva - image_base, (void *) (eaddresses + i));
565 if (!pe_def_file->exports[s].flag_noname)
566 {
567 char *ename = pe_def_file->exports[s].name;
568 bfd_put_32 (abfd, ERVA (enamestr), (void *) enameptrs);
a18b9a3d 569 strcpy (enamestr, ename);
eb8061bf
DD
570 enamestr += strlen (enamestr) + 1;
571 bfd_put_16 (abfd, i, (void *) eordinals);
572 enameptrs++;
d3ca9a53 573 pe_def_file->exports[s].hint = hint++;
eb8061bf
DD
574 }
575 eordinals++;
576 }
577 }
578}
579
580/************************************************************************
581
582 Gather all the relocations and build the .reloc section
583
584 ************************************************************************/
585
586static void
587generate_reloc (abfd, info)
588 bfd *abfd;
589 struct bfd_link_info *info;
590{
591
592 /* for .reloc stuff */
593 bfd_vma *reloc_addresses;
594 int total_relocs = 0;
595 int i, j;
596 unsigned long sec_page = (unsigned long) (-1);
597 unsigned long page_ptr, page_count;
598 int bi;
599 bfd *b;
600 struct sec *s;
601
602 total_relocs = 0;
603 for (b = info->input_bfds; b; b = b->link_next)
604 for (s = b->sections; s; s = s->next)
605 total_relocs += s->reloc_count;
606
607 reloc_addresses = (unsigned long *) xmalloc (total_relocs * sizeof (unsigned long));
608
609 total_relocs = 0;
610 bi = 0;
611 for (bi = 0, b = info->input_bfds; b; bi++, b = b->link_next)
612 {
613 arelent **relocs;
614 int relsize, nrelocs, i;
615
616 for (s = b->sections; s; s = s->next)
617 {
618 unsigned long sec_vma = s->output_section->vma + s->output_offset;
619 asymbol **symbols;
620 int nsyms, symsize;
621
b138a74d
DD
622 /* if it's not loaded, we don't need to relocate it this way */
623 if (!(s->output_section->flags & SEC_LOAD))
624 continue;
625
626 /* I don't know why there would be a reloc for these, but I've
627 seen it happen - DJ */
628 if (s->output_section == &bfd_abs_section)
629 continue;
630
631 if (s->output_section->vma == 0)
632 {
633 /* Huh? Shouldn't happen, but punt if it does */
634 einfo ("DJ: zero vma section reloc detected: `%s' #%d f=%d\n",
635 s->output_section->name, s->output_section->index,
636 s->output_section->flags);
637 continue;
638 }
639
eb8061bf
DD
640 symsize = bfd_get_symtab_upper_bound (b);
641 symbols = (asymbol **) xmalloc (symsize);
642 nsyms = bfd_canonicalize_symtab (b, symbols);
643
644 relsize = bfd_get_reloc_upper_bound (b, s);
645 relocs = (arelent **) xmalloc ((size_t) relsize);
646 nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);
647
648 for (i = 0; i < nrelocs; i++)
649 {
b138a74d
DD
650 if (!relocs[i]->howto->pc_relative
651 && relocs[i]->howto->type != R_IMAGEBASE)
eb8061bf
DD
652 {
653 switch (relocs[i]->howto->bitsize)
654 {
655 case 32:
656 reloc_addresses[total_relocs++] = sec_vma + relocs[i]->address;
657 break;
658 default:
659 /* xgettext:c-format */
660 einfo (_("%XError: %d-bit reloc in dll\n"),
661 relocs[i]->howto->bitsize);
662 break;
663 }
664 }
665 }
666 free (relocs);
667 /* Warning: the allocated symbols are remembered in BFD and reused
668 later, so don't free them! */
3feaa5af 669 /* free (symbols); */
eb8061bf
DD
670 }
671 }
672
673 /* At this point, we have total_relocs relocation addresses in
674 reloc_addresses, which are all suitable for the .reloc section.
675 We must now create the new sections. */
676
677 qsort (reloc_addresses, total_relocs, sizeof (unsigned long), reloc_sort);
678
679 for (i = 0; i < total_relocs; i++)
680 {
681 unsigned long this_page = (reloc_addresses[i] >> 12);
682 if (this_page != sec_page)
683 {
684 reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */
685 reloc_sz += 8;
686 sec_page = this_page;
687 }
688 reloc_sz += 2;
689 }
690 reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */
691
692 reloc_d = (unsigned char *) xmalloc (reloc_sz);
693
694 sec_page = (unsigned long) (-1);
695 reloc_sz = 0;
696 page_ptr = (unsigned long) (-1);
697 page_count = 0;
698 for (i = 0; i < total_relocs; i++)
699 {
700 unsigned long rva = reloc_addresses[i] - image_base;
701 unsigned long this_page = (rva & ~0xfff);
702 if (this_page != sec_page)
703 {
704 while (reloc_sz & 3)
705 reloc_d[reloc_sz++] = 0;
706 if (page_ptr != (unsigned long) (-1))
707 bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
708 bfd_put_32 (abfd, this_page, reloc_d + reloc_sz);
709 page_ptr = reloc_sz;
710 reloc_sz += 8;
711 sec_page = this_page;
712 page_count = 0;
713 }
714 bfd_put_16 (abfd, (rva & 0xfff) + 0x3000, reloc_d + reloc_sz);
715 reloc_sz += 2;
716 page_count++;
717 }
718 while (reloc_sz & 3)
719 reloc_d[reloc_sz++] = 0;
720 if (page_ptr != (unsigned long) (-1))
721 bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
722 while (reloc_sz < reloc_s->_raw_size)
723 reloc_d[reloc_sz++] = 0;
724}
725
726/************************************************************************
727
728 Given the exiting def_file structure, print out a .DEF file that
729 corresponds to it.
730
731 ************************************************************************/
732
733static void
734quoteput (s, f, needs_quotes)
735 char *s;
736 FILE * f;
737 int needs_quotes;
738{
739 char *cp;
740 for (cp = s; *cp; cp++)
741 if (*cp == '\'' || *cp == '"' || *cp == '\\' || isspace (*cp) || *cp == ','
742 || *cp == ';')
743 needs_quotes = 1;
744 if (needs_quotes)
745 {
746 putc ('"', f);
747 while (*s)
748 {
749 if (*s == '"' || *s == '\\')
750 putc ('\\', f);
751 putc (*s, f);
752 s++;
753 }
754 putc ('"', f);
755 }
756 else
757 fputs (s, f);
758}
759
760void
761pe_dll_generate_def_file (pe_out_def_filename)
762 char *pe_out_def_filename;
763{
764 int i;
765 FILE *out = fopen (pe_out_def_filename, "w");
766 if (out == NULL)
767 {
768 /* xgettext:c-format */
769 einfo (_("%s: Can't open output def file %s\n"),
770 program_name, pe_out_def_filename);
771 }
772
e2586bc8 773 if (pe_def_file)
eb8061bf 774 {
e2586bc8
DD
775 if (pe_def_file->name)
776 {
777 if (pe_def_file->is_dll)
778 fprintf (out, "LIBRARY ");
779 else
780 fprintf (out, "NAME ");
781 quoteput (pe_def_file->name, out, 1);
3feaa5af
DD
782 if (pe_data (output_bfd)->pe_opthdr.ImageBase)
783 fprintf (out, " BASE=0x%x", pe_data (output_bfd)->pe_opthdr.ImageBase);
e2586bc8
DD
784 fprintf (out, "\n");
785 }
eb8061bf 786
e2586bc8
DD
787 if (pe_def_file->description)
788 {
789 fprintf (out, "DESCRIPTION ");
790 quoteput (pe_def_file->description, out, 1);
791 fprintf (out, "\n");
792 }
eb8061bf 793
3feaa5af 794 if (pe_def_file->version_minor != -1)
e2586bc8
DD
795 fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major,
796 pe_def_file->version_minor);
3feaa5af 797 else if (pe_def_file->version_major != -1)
e2586bc8
DD
798 fprintf (out, "VERSION %d\n", pe_def_file->version_major);
799
800 if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1)
801 fprintf (out, "\n");
802
803 if (pe_def_file->stack_commit != -1)
804 fprintf (out, "STACKSIZE 0x%x,0x%x\n",
805 pe_def_file->stack_reserve, pe_def_file->stack_commit);
806 else if (pe_def_file->stack_reserve != -1)
807 fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve);
808 if (pe_def_file->heap_commit != -1)
809 fprintf (out, "HEAPSIZE 0x%x,0x%x\n",
810 pe_def_file->heap_reserve, pe_def_file->heap_commit);
811 else if (pe_def_file->heap_reserve != -1)
812 fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve);
813
814 if (pe_def_file->num_section_defs > 0)
eb8061bf 815 {
e2586bc8
DD
816 fprintf (out, "\nSECTIONS\n\n");
817 for (i = 0; i < pe_def_file->num_section_defs; i++)
eb8061bf 818 {
e2586bc8
DD
819 fprintf (out, " ");
820 quoteput (pe_def_file->section_defs[i].name, out, 0);
821 if (pe_def_file->section_defs[i].class)
822 {
823 fprintf (out, " CLASS ");
824 quoteput (pe_def_file->section_defs[i].class, out, 0);
825 }
826 if (pe_def_file->section_defs[i].flag_read)
827 fprintf (out, " READ");
828 if (pe_def_file->section_defs[i].flag_write)
829 fprintf (out, " WRITE");
830 if (pe_def_file->section_defs[i].flag_execute)
831 fprintf (out, " EXECUTE");
832 if (pe_def_file->section_defs[i].flag_shared)
833 fprintf (out, " SHARED");
834 fprintf (out, "\n");
eb8061bf 835 }
eb8061bf 836 }
eb8061bf 837
e2586bc8 838 if (pe_def_file->num_exports > 0)
eb8061bf 839 {
e2586bc8
DD
840 fprintf (out, "\nEXPORTS\n\n");
841 for (i = 0; i < pe_def_file->num_exports; i++)
eb8061bf 842 {
e2586bc8
DD
843 def_file_export *e = pe_def_file->exports + i;
844 fprintf (out, " ");
845 quoteput (e->name, out, 0);
846 if (e->internal_name && strcmp (e->internal_name, e->name))
847 {
848 fprintf (out, " = ");
849 quoteput (e->internal_name, out, 0);
850 }
851 if (e->ordinal != -1)
852 fprintf (out, " @%d", e->ordinal);
853 if (e->flag_private)
854 fprintf (out, " PRIVATE");
855 if (e->flag_constant)
856 fprintf (out, " CONSTANT");
857 if (e->flag_noname)
858 fprintf (out, " NONAME");
859 if (e->flag_data)
860 fprintf (out, " DATA");
861
862 fprintf (out, "\n");
eb8061bf 863 }
eb8061bf 864 }
eb8061bf 865
e2586bc8 866 if (pe_def_file->num_imports > 0)
eb8061bf 867 {
e2586bc8
DD
868 fprintf (out, "\nIMPORTS\n\n");
869 for (i = 0; i < pe_def_file->num_imports; i++)
eb8061bf 870 {
e2586bc8
DD
871 def_file_import *im = pe_def_file->imports + i;
872 fprintf (out, " ");
873 if (im->internal_name
874 && (!im->name || strcmp (im->internal_name, im->name)))
875 {
876 quoteput (im->internal_name, out, 0);
877 fprintf (out, " = ");
878 }
879 quoteput (im->module->name, out, 0);
880 fprintf (out, ".");
881 if (im->name)
882 quoteput (im->name, out, 0);
883 else
884 fprintf (out, "%d", im->ordinal);
885 fprintf (out, "\n");
eb8061bf 886 }
eb8061bf
DD
887 }
888 }
e2586bc8
DD
889 else
890 fprintf (out, _("; no contents available\n"));
eb8061bf
DD
891
892 if (fclose (out) == EOF)
893 {
894 /* xgettext:c-format */
895 einfo (_("%P: Error closing file `%s'\n"), pe_out_def_filename);
896 }
897}
898
d3ca9a53
DD
899/************************************************************************
900
901 Generate the import library
902
903 ************************************************************************/
904
905static asymbol **symtab;
906static int symptr;
907static int tmp_seq;
908static const char *dll_filename;
909static char *dll_symname;
910
3feaa5af
DD
911#define UNDSEC (asection *) &bfd_und_section
912
d3ca9a53
DD
913static asection *
914quick_section(abfd, name, flags, align)
915 bfd *abfd;
916 const char *name;
917 int flags;
918 int align;
919{
920 asection *sec;
921 asymbol *sym;
922
3feaa5af
DD
923 sec = bfd_make_section_old_way (abfd, name);
924 bfd_set_section_flags (abfd, sec, flags
925 | SEC_ALLOC
926 | SEC_LOAD
927 | SEC_KEEP
928 );
d3ca9a53 929 bfd_set_section_alignment (abfd, sec, align);
3feaa5af
DD
930 /* remember to undo this before trying to link internally! */
931 sec->output_section = sec;
d3ca9a53 932
3feaa5af 933 sym = bfd_make_empty_symbol (abfd);
d3ca9a53
DD
934 symtab[symptr++] = sym;
935 sym->name = sec->name;
936 sym->section = sec;
937 sym->flags = BSF_LOCAL;
938 sym->value = 0;
939
940 return sec;
941}
942
943static void
944quick_symbol (abfd, n1, n2, n3, sec, flags, addr)
945 bfd *abfd;
946 char *n1;
947 char *n2;
948 char *n3;
949 asection *sec;
950 int flags;
951 int addr;
952{
3feaa5af
DD
953 asymbol *sym;
954 struct bfd_link_hash_entry *blhe;
955 char *name = (char *) xmalloc (strlen (n1) + strlen (n2) + strlen (n3) + 1);
d3ca9a53
DD
956 strcpy (name, n1);
957 strcat (name, n2);
958 strcat (name, n3);
3feaa5af 959 sym = bfd_make_empty_symbol (abfd);
d3ca9a53
DD
960 sym->name = name;
961 sym->section = sec;
962 sym->flags = flags;
963 sym->value = addr;
964 symtab[symptr++] = sym;
965}
966
3feaa5af 967static arelent *reltab = 0;
d3ca9a53
DD
968static int relcount = 0, relsize = 0;
969
970static void
971quick_reloc (abfd, address, which_howto, symidx)
972 bfd *abfd;
973 int address;
974 int which_howto;
975 int symidx;
976{
977 if (relcount >= (relsize-1))
978 {
979 relsize += 10;
980 if (reltab)
3feaa5af 981 reltab = (arelent *) xrealloc (reltab, relsize * sizeof (arelent));
d3ca9a53 982 else
3feaa5af 983 reltab = (arelent *) xmalloc (relsize * sizeof (arelent));
d3ca9a53 984 }
3feaa5af
DD
985 reltab[relcount].address = address;
986 reltab[relcount].addend = 0;
987 reltab[relcount].howto = bfd_reloc_type_lookup (abfd, which_howto);
988 reltab[relcount].sym_ptr_ptr = symtab + symidx;
d3ca9a53
DD
989 relcount++;
990}
991
992static void
993save_relocs (asection *sec)
994{
3feaa5af
DD
995 int i;
996 sec->relocation = reltab;
d3ca9a53 997 sec->reloc_count = relcount;
3feaa5af
DD
998 sec->orelocation = (arelent **) xmalloc ((relcount+1) * sizeof (arelent *));
999 for (i=0; i<relcount; i++)
1000 sec->orelocation[i] = sec->relocation + i;
1001 sec->orelocation[relcount] = 0;
1002 sec->flags |= SEC_RELOC;
d3ca9a53
DD
1003 reltab = 0;
1004 relcount = relsize = 0;
1005}
1006
d3ca9a53
DD
1007/*
1008 * .section .idata$2
1009 * .global __head_my_dll
1010 * __head_my_dll:
1011 * .rva hname
1012 * .long 0
1013 * .long 0
1014 * .rva __my_dll_iname
1015 * .rva fthunk
1016 *
1017 * .section .idata$5
1018 * .long 0
1019 * fthunk:
1020 *
1021 * .section .idata$4
1022 * .long 0
1023 * hname:
1024 */
1025
c59356d3 1026static bfd *
d3ca9a53
DD
1027make_head (parent)
1028 bfd *parent;
1029{
1030 asection *id2, *id5, *id4;
1031 unsigned char *d2, *d5, *d4;
c59356d3
DD
1032 char *oname;
1033 bfd *abfd;
d3ca9a53 1034
c59356d3
DD
1035 oname = (char *) xmalloc (20);
1036 sprintf (oname, "d%06d.o", tmp_seq);
1037 tmp_seq++;
1038
1039 abfd = bfd_create (oname, parent);
3feaa5af 1040 bfd_find_target ("pe-i386", abfd);
d3ca9a53 1041 bfd_make_writable (abfd);
3feaa5af 1042
d3ca9a53
DD
1043 bfd_set_format (abfd, bfd_object);
1044 bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
1045
1046 symptr = 0;
1047 symtab = (asymbol **) xmalloc (6 * sizeof (asymbol *));
3feaa5af
DD
1048 id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
1049 id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
1050 id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
d3ca9a53
DD
1051 quick_symbol (abfd, "__head_", dll_symname, "", id2, BSF_GLOBAL, 0);
1052 quick_symbol (abfd, "_", dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
1053
3feaa5af 1054 bfd_set_section_size (abfd, id2, 20);
d3ca9a53 1055 d2 = (unsigned char *) xmalloc (20);
3feaa5af 1056 id2->contents = d2;
d3ca9a53
DD
1057 memset (d2, 0, 20);
1058 d2[0] = d2[16] = 4; /* reloc addend */
3feaa5af
DD
1059 quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
1060 quick_reloc (abfd, 12, BFD_RELOC_RVA, 4);
1061 quick_reloc (abfd, 16, BFD_RELOC_RVA, 1);
1062 save_relocs (id2);
d3ca9a53
DD
1063
1064 bfd_set_section_size (abfd, id5, 4);
1065 d5 = (unsigned char *) xmalloc (4);
3feaa5af 1066 id5->contents = d5;
d3ca9a53
DD
1067 memset (d5, 0, 4);
1068
1069 bfd_set_section_size (abfd, id4, 4);
1070 d4 = (unsigned char *) xmalloc (4);
3feaa5af 1071 id4->contents = d4;
d3ca9a53
DD
1072 memset (d4, 0, 4);
1073
3feaa5af 1074 bfd_set_symtab (abfd, symtab, symptr);
d3ca9a53 1075
3feaa5af
DD
1076 bfd_set_section_contents (abfd, id2, d2, 0, 20);
1077 bfd_set_section_contents (abfd, id5, d5, 0, 4);
1078 bfd_set_section_contents (abfd, id4, d4, 0, 4);
1079
d3ca9a53
DD
1080 bfd_make_readable (abfd);
1081 return abfd;
d3ca9a53
DD
1082}
1083
1084/*
1085 * .section .idata$4
1086 * .long 0
1087 * .section .idata$5
1088 * .long 0
1089 * .section idata$7
1090 * .global __my_dll_iname
1091 *__my_dll_iname:
1092 * .asciz "my.dll"
1093 */
1094
c59356d3 1095static bfd *
d3ca9a53
DD
1096make_tail (parent)
1097 bfd *parent;
1098{
1099 asection *id4, *id5, *id7;
1100 unsigned char *d4, *d5, *d7;
1101 int len;
c59356d3
DD
1102 char *oname;
1103 bfd *abfd;
1104
1105 oname = (char *) xmalloc (20);
1106 sprintf (oname, "d%06d.o", tmp_seq);
1107 tmp_seq++;
d3ca9a53 1108
c59356d3 1109 abfd = bfd_create (oname, parent);
3feaa5af 1110 bfd_find_target ("pe-i386", abfd);
d3ca9a53 1111 bfd_make_writable (abfd);
3feaa5af 1112
d3ca9a53
DD
1113 bfd_set_format (abfd, bfd_object);
1114 bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
1115
1116 symptr = 0;
1117 symtab = (asymbol **) xmalloc (5 * sizeof (asymbol *));
3feaa5af
DD
1118 id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
1119 id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
1120 id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
d3ca9a53
DD
1121 quick_symbol (abfd, "_", dll_symname, "_iname", id7, BSF_GLOBAL, 0);
1122
3feaa5af 1123 bfd_set_section_size (abfd, id4, 4);
d3ca9a53 1124 d4 = (unsigned char *) xmalloc (4);
3feaa5af 1125 id4->contents = d4;
d3ca9a53
DD
1126 memset (d4, 0, 4);
1127
1128 bfd_set_section_size (abfd, id5, 4);
1129 d5 = (unsigned char *) xmalloc (4);
3feaa5af 1130 id5->contents = d5;
d3ca9a53
DD
1131 memset (d5, 0, 4);
1132
3feaa5af 1133 len = strlen (dll_filename)+1;
d3ca9a53
DD
1134 if (len & 1)
1135 len ++;
1136 bfd_set_section_size (abfd, id7, len);
1137 d7 = (unsigned char *) xmalloc (len);
3feaa5af 1138 id7->contents = d7;
d3ca9a53
DD
1139 strcpy (d7, dll_filename);
1140
3feaa5af 1141 bfd_set_symtab (abfd, symtab, symptr);
d3ca9a53 1142
3feaa5af
DD
1143 bfd_set_section_contents (abfd, id4, d4, 0, 4);
1144 bfd_set_section_contents (abfd, id5, d5, 0, 4);
1145 bfd_set_section_contents (abfd, id7, d7, 0, len);
d3ca9a53 1146
d3ca9a53
DD
1147 bfd_make_readable (abfd);
1148 return abfd;
d3ca9a53
DD
1149}
1150
1151/*
1152 * .text
1153 * .global _function
1154 * .global ___imp_function
1155 * .global __imp__function
1156 *_function:
1157 * jmp *__imp__function:
1158 *
1159 * .section idata$7
1160 * .long __head_my_dll
1161 *
1162 * .section .idata$5
1163 *___imp_function:
1164 *__imp__function:
1165 *iat?
1166 * .section .idata$4
1167 *iat?
1168 * .section .idata$6
1169 *ID<ordinal>:
1170 * .short <hint>
1171 * .asciz "function" xlate? (add underscore, kill at)
1172 */
1173
c59356d3 1174static unsigned char jmp_ix86_bytes[] = {
d3ca9a53
DD
1175 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
1176};
1177
1178
c59356d3 1179static bfd *
d3ca9a53
DD
1180make_one (exp, parent)
1181 def_file_export *exp;
1182 bfd *parent;
1183{
1184 asection *tx, *id7, *id5, *id4, *id6;
1185 unsigned char *td, *d7, *d5, *d4, *d6;
1186 int len;
1187 char *oname;
1188 bfd *abfd;
1189
1190 oname = (char *) xmalloc (20);
c59356d3 1191 sprintf (oname, "d%06d.o", tmp_seq);
d3ca9a53 1192 tmp_seq++;
c59356d3 1193
d3ca9a53 1194 abfd = bfd_create (oname, parent);
3feaa5af 1195 bfd_find_target ("pe-i386", abfd);
d3ca9a53 1196 bfd_make_writable (abfd);
3feaa5af 1197
d3ca9a53
DD
1198 bfd_set_format (abfd, bfd_object);
1199 bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
1200
1201 symptr = 0;
1202 symtab = (asymbol **) xmalloc (10 * sizeof (asymbol *));
3feaa5af
DD
1203 tx = quick_section (abfd, ".text", SEC_CODE|SEC_HAS_CONTENTS, 2);
1204 id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
1205 id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
1206 id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
1207 id6 = quick_section (abfd, ".idata$6", SEC_HAS_CONTENTS, 2);
1208 quick_symbol (abfd, "_", exp->internal_name, "", tx, BSF_GLOBAL, 0);
d3ca9a53 1209 quick_symbol (abfd, "__head_", dll_symname, "", UNDSEC, BSF_GLOBAL, 0);
3feaa5af
DD
1210 quick_symbol (abfd, "___imp_", exp->internal_name, "", id5, BSF_GLOBAL, 0);
1211 quick_symbol (abfd, "__imp__", exp->internal_name, "", id5, BSF_GLOBAL, 0);
d3ca9a53
DD
1212
1213 bfd_set_section_size (abfd, tx, 8);
1214 td = (unsigned char *) xmalloc (8);
3feaa5af 1215 tx->contents = td;
d3ca9a53
DD
1216 memcpy (td, jmp_ix86_bytes, 8);
1217 quick_reloc (abfd, 2, BFD_RELOC_32, 2);
1218 save_relocs (tx);
1219
3feaa5af 1220 bfd_set_section_size (abfd, id7, 4);
d3ca9a53 1221 d7 = (unsigned char *) xmalloc (4);
3feaa5af 1222 id7->contents = d7;
d3ca9a53
DD
1223 memset (d7, 0, 4);
1224 quick_reloc (abfd, 0, BFD_RELOC_RVA, 6);
1225 save_relocs (id7);
1226
1227 bfd_set_section_size (abfd, id5, 4);
1228 d5 = (unsigned char *) xmalloc (4);
3feaa5af 1229 id5->contents = d5;
d3ca9a53
DD
1230 memset (d5, 0, 4);
1231 if (exp->flag_noname)
1232 {
1233 d5[0] = exp->ordinal;
1234 d5[1] = exp->ordinal >> 8;
1235 d5[3] = 0x80;
1236 }
1237 else
1238 {
1239 quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
1240 save_relocs (id5);
1241 }
1242
1243 bfd_set_section_size (abfd, id4, 4);
1244 d4 = (unsigned char *) xmalloc (4);
3feaa5af 1245 id4->contents = d4;
d3ca9a53
DD
1246 memset (d4, 0, 4);
1247 if (exp->flag_noname)
1248 {
1249 d5[0] = exp->ordinal;
1250 d5[1] = exp->ordinal >> 8;
1251 d5[3] = 0x80;
1252 }
1253 else
1254 {
1255 quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
1256 save_relocs (id4);
1257 }
1258
1259 if (exp->flag_noname)
1260 {
1261 len = 0;
3feaa5af 1262 bfd_set_section_size (abfd, id6, 0);
d3ca9a53
DD
1263 }
1264 else
1265 {
3feaa5af 1266 len = strlen (exp->name) + 3;
d3ca9a53
DD
1267 if (len & 1)
1268 len++;
3feaa5af 1269 bfd_set_section_size (abfd, id6, len);
d3ca9a53 1270 d6 = (unsigned char *) xmalloc (len);
3feaa5af 1271 id6->contents = d6;
d3ca9a53
DD
1272 memset (d6, 0, len);
1273 d6[0] = exp->hint & 0xff;
1274 d6[1] = exp->hint >> 8;
3feaa5af 1275 strcpy (d6+2, exp->name);
d3ca9a53
DD
1276 }
1277
3feaa5af 1278 bfd_set_symtab (abfd, symtab, symptr);
d3ca9a53 1279
3feaa5af
DD
1280 bfd_set_section_contents (abfd, tx, td, 0, 4);
1281 bfd_set_section_contents (abfd, id7, d7, 0, 4);
1282 bfd_set_section_contents (abfd, id5, d5, 0, 4);
1283 bfd_set_section_contents (abfd, id4, d4, 0, 4);
1284 if (!exp->flag_noname)
1285 bfd_set_section_contents (abfd, id6, d6, 0, len);
d3ca9a53 1286
d3ca9a53
DD
1287 bfd_make_readable (abfd);
1288 return abfd;
d3ca9a53
DD
1289}
1290
1291void
1292pe_dll_generate_implib (def, impfilename)
1293 def_file *def;
1294 char *impfilename;
1295{
1296 int i;
d3ca9a53
DD
1297 bfd *ar_head;
1298 bfd *ar_tail;
1299 bfd *outarch;
3feaa5af 1300 bfd *head = 0;
d3ca9a53
DD
1301
1302 dll_filename = def->name;
1303 if (dll_filename == 0)
1304 {
1305 dll_filename = dll_name;
1306 for (i=0; impfilename[i]; i++)
1307 if (impfilename[i] == '/' || impfilename[i] == '\\')
1308 dll_filename = impfilename+1;
1309 }
1310 dll_symname = xstrdup (dll_filename);
1311 for (i=0; dll_symname[i]; i++)
1312 if (!isalnum (dll_symname[i]))
1313 dll_symname[i] = '_';
1314
1315 unlink (impfilename);
1316
1317 outarch = bfd_openw (impfilename, 0);
1318
1319 if (!outarch)
1320 {
1321 /* xgettext:c-format */
1322 einfo (_("%XCan't open .lib file: %s\n"), impfilename);
1323 return;
1324 }
1325
1326 /* xgettext:c-format */
1327 einfo (_("Creating library file: %s\n"), impfilename);
1328
1329 bfd_set_format (outarch, bfd_archive);
1330 outarch->has_armap = 1;
1331
1332 /* Work out a reasonable size of things to put onto one line. */
1333
1334 ar_head = make_head (outarch);
1335 ar_tail = make_tail (outarch);
1336
1337 if (ar_head == NULL || ar_tail == NULL)
1338 return;
1339
1340 for (i = 0; i<def->num_exports; i++)
1341 {
3feaa5af
DD
1342 /* The import library doesn't know about the internal name */
1343 char *internal = def->exports[i].internal_name;
1344 bfd *n;
1345 def->exports[i].internal_name = def->exports[i].name;
1346 n = make_one (def->exports+i, outarch);
d3ca9a53
DD
1347 n->next = head;
1348 head = n;
3feaa5af 1349 def->exports[i].internal_name = internal;
d3ca9a53
DD
1350 }
1351
1352 /* Now stick them all into the archive */
1353
1354 ar_head->next = head;
1355 ar_tail->next = ar_head;
1356 head = ar_tail;
1357
1358 if (! bfd_set_archive_head (outarch, head))
1359 einfo ("%Xbfd_set_archive_head: %s\n", bfd_errmsg (bfd_get_error ()));
1360
1361 if (! bfd_close (outarch))
1362 einfo ("%Xbfd_close %s: %s\n", impfilename, bfd_errmsg (bfd_get_error ()));
1363
1364 while (head != NULL)
1365 {
1366 bfd *n = head->next;
1367 bfd_close (head);
1368 head = n;
1369 }
3feaa5af
DD
1370}
1371
1372static void
1373add_bfd_to_link (abfd, name, link_info)
1374 bfd *abfd;
1375 char *name;
1376 struct bfd_link_info *link_info;
1377{
1378 lang_input_statement_type *fake_file;
1379 fake_file = lang_add_input_file (name,
1380 lang_input_file_is_fake_enum,
1381 NULL);
1382 fake_file->the_bfd = abfd;
1383 ldlang_add_file (fake_file);
1384 if (!bfd_link_add_symbols (abfd, link_info))
1385 einfo ("%Xaddsym %s: %s\n", name, bfd_errmsg (bfd_get_error ()));
1386}
1387
1388void
1389pe_process_import_defs (output_bfd, link_info)
1390 bfd *output_bfd;
1391 struct bfd_link_info *link_info;
1392{
1393 def_file_module *module;
1394
1395 if (!pe_def_file)
1396 return;
d3ca9a53 1397
3feaa5af 1398 for (module = pe_def_file->modules; module; module = module->next)
d3ca9a53 1399 {
3feaa5af
DD
1400 bfd *ar_head;
1401 bfd *ar_tail;
1402 int i, do_this_dll;
1403
1404 dll_filename = module->name;
1405 dll_symname = xstrdup (module->name);
1406 for (i=0; dll_symname[i]; i++)
1407 if (!isalnum (dll_symname[i]))
1408 dll_symname[i] = '_';
1409
1410 do_this_dll = 0;
1411
1412 for (i=0; i<pe_def_file->num_imports; i++)
1413 if (pe_def_file->imports[i].module == module)
1414 {
1415 def_file_export exp;
1416 bfd *n;
1417 struct bfd_link_hash_entry *blhe;
1418
1419 /* see if we need this import */
1420 char *name = (char *) xmalloc (strlen (pe_def_file->imports[i].internal_name) + 2);
1421 sprintf (name, "_%s", pe_def_file->imports[i].internal_name);
1422 blhe = bfd_link_hash_lookup (link_info->hash, name,
1423 false, false, false);
1424 free (name);
1425 if (blhe && blhe->type == bfd_link_hash_undefined)
1426 {
c59356d3 1427 bfd *one;
3feaa5af
DD
1428 /* we do */
1429 if (!do_this_dll)
1430 {
c59356d3
DD
1431 bfd *ar_head = make_head (output_bfd);
1432 add_bfd_to_link (ar_head, ar_head->filename, link_info);
3feaa5af
DD
1433 do_this_dll = 1;
1434 }
1435 exp.internal_name = pe_def_file->imports[i].internal_name;
1436 exp.name = pe_def_file->imports[i].name;
1437 exp.ordinal = pe_def_file->imports[i].ordinal;
c59356d3 1438 exp.hint = exp.ordinal;
3feaa5af
DD
1439 exp.flag_private = 0;
1440 exp.flag_constant = 0;
1441 exp.flag_data = 0;
1442 exp.flag_noname = exp.name ? 0 : 1;
c59356d3
DD
1443 one = make_one (&exp, output_bfd);
1444 add_bfd_to_link (one, one->filename, link_info);
3feaa5af
DD
1445 }
1446 }
1447 if (do_this_dll)
c59356d3
DD
1448 {
1449 bfd *ar_tail = make_tail (output_bfd);
1450 add_bfd_to_link (ar_tail, ar_tail->filename, link_info);
1451 }
3feaa5af
DD
1452
1453 free (dll_symname);
d3ca9a53
DD
1454 }
1455}
1456
c59356d3
DD
1457/************************************************************************
1458
1459 We were handed a *.DLL file. Parse it and turn it into a set of
1460 IMPORTS directives in the def file. Return true if the file was
1461 handled, false if not.
1462
1463 ************************************************************************/
1464
1465static unsigned int
1466pe_get16 (abfd, where)
1467 bfd *abfd;
1468 int where;
1469{
1470 unsigned char b[2];
1471 bfd_seek (abfd, where, SEEK_SET);
1472 bfd_read (b, 1, 2, abfd);
1473 return b[0] + (b[1]<<8);
1474}
1475
1476static unsigned int
1477pe_get32 (abfd, where)
1478 bfd *abfd;
1479 int where;
1480{
1481 unsigned char b[4];
1482 bfd_seek (abfd, where, SEEK_SET);
1483 bfd_read (b, 1, 4, abfd);
1484 return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
1485}
1486
1487static unsigned int
1488pe_as16 (ptr)
1489 void *ptr;
1490{
1491 unsigned char *b = ptr;
1492 return b[0] + (b[1]<<8);
1493}
1494
1495static unsigned int
1496pe_as32 (ptr)
1497 void *ptr;
1498{
1499 unsigned char *b = ptr;
1500 return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
1501}
1502
1503extern int bfd_pe_dll_not_recognized_hack;
1504
1505boolean
1506pe_implied_import_dll (filename)
1507 char *filename;
1508{
1509 bfd *dll;
1510 unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
1511 unsigned long export_rva, export_size, nsections, secptr, expptr;
1512 unsigned char *expdata, *erva;
1513 unsigned long name_rvas, ordinals, nexp, ordbase;
1514 char *dll_name;
1515
1516 /* No, I can't use bfd here. kernel32.dll puts its export table in
1517 the middle of the .rdata section. */
1518
1519 bfd_pe_dll_not_recognized_hack = 0;
1520 dll = bfd_openr (filename, "pei-i386");
1521 if (!dll)
1522 {
1523 einfo ("%Xopen %s: %s\n", filename, bfd_errmsg (bfd_get_error ()));
1524 bfd_pe_dll_not_recognized_hack = 1;
1525 return false;
1526 }
1527 /* PEI dlls seem to be bfd_objects */
1528 if (!bfd_check_format (dll, bfd_object))
1529 {
1530 einfo ("%X%s: this doesn't appear to be a DLL\n", filename);
1531 bfd_pe_dll_not_recognized_hack = 1;
1532 return false;
1533 }
1534 bfd_pe_dll_not_recognized_hack = 1;
1535 printf("dj: importing dll %s at %x\n", filename, dll->where);
1536
1537 dll_name = filename;
1538 for (i=0; filename[i]; i++)
1539 if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
1540 dll_name = filename + i + 1;
1541
1542 pe_header_offset = pe_get32 (dll, 0x3c);
1543 opthdr_ofs = pe_header_offset + 4 + 20;
1544 num_entries = pe_get32 (dll, opthdr_ofs + 92);
1545 if (num_entries < 1) /* no exports */
1546 return false;
1547 export_rva = pe_get32 (dll, opthdr_ofs + 96);
1548 export_size = pe_get32 (dll, opthdr_ofs + 100);
1549 nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
1550 secptr = (pe_header_offset + 4 + 20 +
1551 pe_get16 (dll, pe_header_offset + 4 + 16));
1552 expptr = 0;
1553 printf("export: rva=%08x size=%08x secptr=%08x\n",
1554 export_rva, export_size, secptr);
1555 for (i=0; i<nsections; i++)
1556 {
1557 char sname[8];
1558 unsigned long secptr1 = secptr + 40 * i;
1559 unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
1560 unsigned long vsize = pe_get32 (dll, secptr1 + 16);
1561 unsigned long fptr = pe_get32 (dll, secptr1 + 20);
1562 bfd_seek(dll, secptr1, SEEK_SET);
1563 bfd_read(sname, 1, 8, dll);
1564 printf("sec: %.8s addr=%08x size=%08x fptr=%08x\n",
1565 sname, vaddr, vsize, fptr);
1566 if (vaddr <= export_rva && vaddr+vsize > export_rva)
1567 {
1568 expptr = fptr + (export_rva - vaddr);
1569 if (export_rva + export_size > vaddr + vsize)
1570 export_size = vsize - (export_rva - vaddr);
1571 break;
1572 }
1573 }
1574 printf("expptr=%08x size=%08x\n", expptr, export_size);
1575
1576 expdata = (unsigned char *) xmalloc (export_size);
1577 bfd_seek (dll, expptr, SEEK_SET);
1578 bfd_read (expdata, 1, export_size, dll);
1579 erva = expdata - export_rva;
1580
1581 if (pe_def_file == 0)
1582 pe_def_file = def_file_empty();
1583
1584 nexp = pe_as32 (expdata+24);
1585 name_rvas = pe_as32 (expdata+32);
1586 ordinals = pe_as32 (expdata+36);
1587 ordbase = pe_as32 (expdata+16);
1588 printf("%d exports ob=%d\n", nexp, ordbase);
1589 for (i=0; i<nexp; i++)
1590 {
1591 unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
1592 def_file_import *imp;
1593 imp = def_file_add_import (pe_def_file, erva+name_rva, dll_name,
1594 i, 0);
1595 }
1596
1597 return true;
1598}
1599
eb8061bf
DD
1600/************************************************************************
1601
1602 These are the main functions, called from the emulation. The first
1603 is called after the bfds are read, so we can guess at how much space
1604 we need. The second is called after everything is placed, so we
1605 can put the right values in place.
1606
1607 ************************************************************************/
1608
1609void
1610pe_dll_build_sections (abfd, info)
1611 bfd *abfd;
1612 struct bfd_link_info *info;
1613{
1614 process_def_file (abfd, info);
1615
1616 generate_edata (abfd, info);
1617 build_filler_bfd ();
1618}
1619
1620void
1621pe_dll_fill_sections (abfd, info)
1622 bfd *abfd;
1623 struct bfd_link_info *info;
1624{
1625 image_base = pe_data (abfd)->pe_opthdr.ImageBase;
1626
1627 generate_reloc (abfd, info);
1628 if (reloc_sz > 0)
1629 {
1630 bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
1631
1632 /* Resize the sections. */
1633 lang_size_sections (stat_ptr->head, abs_output_section,
1634 &stat_ptr->head, 0, (bfd_vma) 0, false);
1635
1636 /* Redo special stuff. */
1637 ldemul_after_allocation ();
1638
1639 /* Do the assignments again. */
1640 lang_do_assignments (stat_ptr->head,
1641 abs_output_section,
1642 (fill_type) 0, (bfd_vma) 0);
1643 }
1644
1645 fill_edata (abfd, info);
1646
1647 pe_data (abfd)->dll = 1;
1648
1649 edata_s->contents = edata_d;
1650 reloc_s->contents = reloc_d;
1651}
This page took 0.365567 seconds and 4 git commands to generate.