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