OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [ld/] [emultempl/] [pep.em] - Blame information for rev 307

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
# This shell script emits a C file. -*- C -*-
2
# It does some substitutions.
3
test -z "${ENTRY}" && ENTRY="_mainCRTStartup"
4
if [ -z "$MACHINE" ]; then
5
  OUTPUT_ARCH=${ARCH}
6
else
7
  OUTPUT_ARCH=${ARCH}:${MACHINE}
8
fi
9
rm -f e${EMULATION_NAME}.c
10
(echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
11
fragment <
12
/* Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
13
   Written by Kai Tietz, OneVision Software GmbH&CoKg.
14
 
15
   This file is part of the GNU Binutils.
16
 
17
   This program is free software; you can redistribute it and/or modify
18
   it under the terms of the GNU General Public License as published by
19
   the Free Software Foundation; either version 3 of the License, or
20
   (at your option) any later version.
21
 
22
   This program is distributed in the hope that it will be useful,
23
   but WITHOUT ANY WARRANTY; without even the implied warranty of
24
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
   GNU General Public License for more details.
26
 
27
   You should have received a copy of the GNU General Public License
28
   along with this program; if not, write to the Free Software
29
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
30
   MA 02110-1301, USA.  */
31
 
32
 
33
/* For WINDOWS_XP64 and higher */
34
/* Based on pe.em, but modified for 64 bit support.  */
35
 
36
#define TARGET_IS_${EMULATION_NAME}
37
 
38
#define COFF_IMAGE_WITH_PE
39
#define COFF_WITH_PE
40
#define COFF_WITH_pex64
41
 
42
#include "sysdep.h"
43
#include "bfd.h"
44
#include "bfdlink.h"
45
#include "getopt.h"
46
#include "libiberty.h"
47
#include "ld.h"
48
#include "ldmain.h"
49
#include "ldexp.h"
50
#include "ldlang.h"
51
#include "ldfile.h"
52
#include "ldemul.h"
53
#include 
54
#include "ldlex.h"
55
#include "ldmisc.h"
56
#include "ldctor.h"
57
#include "coff/internal.h"
58
 
59
/* FIXME: See bfd/peXXigen.c for why we include an architecture specific
60
   header in generic PE code.  */
61
#include "coff/x86_64.h"
62
#include "coff/pe.h"
63
 
64
/* FIXME: This is a BFD internal header file, and we should not be
65
   using it here.  */
66
#include "../bfd/libcoff.h"
67
 
68
#undef  AOUTSZ
69
#define AOUTSZ          PEPAOUTSZ
70
#define PEAOUTHDR       PEPAOUTHDR
71
 
72
#include "deffile.h"
73
#include "pep-dll.h"
74
#include "safe-ctype.h"
75
 
76
/* Permit the emulation parameters to override the default section
77
   alignment by setting OVERRIDE_SECTION_ALIGNMENT.  FIXME: This makes
78
   it seem that include/coff/internal.h should not define
79
   PE_DEF_SECTION_ALIGNMENT.  */
80
#if PE_DEF_SECTION_ALIGNMENT != ${OVERRIDE_SECTION_ALIGNMENT:-PE_DEF_SECTION_ALIGNMENT}
81
#undef  PE_DEF_SECTION_ALIGNMENT
82
#define PE_DEF_SECTION_ALIGNMENT ${OVERRIDE_SECTION_ALIGNMENT}
83
#endif
84
 
85
#ifdef TARGET_IS_i386pep
86
#define DLL_SUPPORT
87
#endif
88
 
89
#if defined(TARGET_IS_i386pep) || ! defined(DLL_SUPPORT)
90
#define PE_DEF_SUBSYSTEM                3
91
#else
92
#undef  NT_EXE_IMAGE_BASE
93
#define NT_EXE_IMAGE_BASE               0x00010000
94
#undef  PE_DEF_SECTION_ALIGNMENT
95
#define PE_DEF_SUBSYSTEM                2
96
#undef  PE_DEF_FILE_ALIGNMENT
97
#define PE_DEF_FILE_ALIGNMENT           0x00000200
98
#define PE_DEF_SECTION_ALIGNMENT        0x00000400
99
#endif
100
 
101
 
102
static struct internal_extra_pe_aouthdr pep;
103
static int dll;
104
static flagword real_flags = IMAGE_FILE_LARGE_ADDRESS_AWARE;
105
static int support_old_code = 0;
106
static lang_assignment_statement_type *image_base_statement = 0;
107
 
108
#ifdef DLL_SUPPORT
109
static int    pep_enable_stdcall_fixup = 1; /* 0=disable 1=enable (default).  */
110
static char * pep_out_def_filename = NULL;
111
static char * pep_implib_filename = NULL;
112
static int    pep_enable_auto_image_base = 0;
113
static char * pep_dll_search_prefix = NULL;
114
#endif
115
 
116
extern const char *output_filename;
117
 
118
static void
119
gld_${EMULATION_NAME}_before_parse (void)
120
{
121
  ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
122
  output_filename = "${EXECUTABLE_NAME:-a.exe}";
123
#ifdef DLL_SUPPORT
124
  config.dynamic_link = TRUE;
125
  config.has_shared = 1;
126
  link_info.pei386_auto_import = -1;
127
  link_info.pei386_runtime_pseudo_reloc = -1;
128
 
129
#if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2)
130
  lang_default_entry ("_WinMainCRTStartup");
131
#else
132
  lang_default_entry ("${ENTRY}");
133
#endif
134
#endif
135
}
136
 
137
/* PE format extra command line options.  */
138
 
139
/* Used for setting flags in the PE header.  */
140
enum options
141
{
142
  OPTION_BASE_FILE = 300 + 1,
143
  OPTION_DLL,
144
  OPTION_FILE_ALIGNMENT,
145
  OPTION_IMAGE_BASE,
146
  OPTION_MAJOR_IMAGE_VERSION,
147
  OPTION_MAJOR_OS_VERSION,
148
  OPTION_MAJOR_SUBSYSTEM_VERSION,
149
  OPTION_MINOR_IMAGE_VERSION,
150
  OPTION_MINOR_OS_VERSION,
151
  OPTION_MINOR_SUBSYSTEM_VERSION,
152
  OPTION_SECTION_ALIGNMENT,
153
  OPTION_STACK,
154
  OPTION_SUBSYSTEM,
155
  OPTION_HEAP,
156
  OPTION_SUPPORT_OLD_CODE,
157
  OPTION_OUT_DEF,
158
  OPTION_EXPORT_ALL,
159
  OPTION_EXCLUDE_SYMBOLS,
160
  OPTION_KILL_ATS,
161
  OPTION_STDCALL_ALIASES,
162
  OPTION_ENABLE_STDCALL_FIXUP,
163
  OPTION_DISABLE_STDCALL_FIXUP,
164
  OPTION_IMPLIB_FILENAME,
165
  OPTION_WARN_DUPLICATE_EXPORTS,
166
  OPTION_IMP_COMPAT,
167
  OPTION_ENABLE_AUTO_IMAGE_BASE,
168
  OPTION_DISABLE_AUTO_IMAGE_BASE,
169
  OPTION_DLL_SEARCH_PREFIX,
170
  OPTION_NO_DEFAULT_EXCLUDES,
171
  OPTION_DLL_ENABLE_AUTO_IMPORT,
172
  OPTION_DLL_DISABLE_AUTO_IMPORT,
173
  OPTION_ENABLE_EXTRA_PE_DEBUG,
174
  OPTION_EXCLUDE_LIBS,
175
  OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC,
176
  OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC
177
};
178
 
179
static void
180
gld${EMULATION_NAME}_add_options
181
  (int ns ATTRIBUTE_UNUSED,
182
   char **shortopts ATTRIBUTE_UNUSED,
183
   int nl,
184
   struct option **longopts,
185
   int nrl ATTRIBUTE_UNUSED,
186
   struct option **really_longopts ATTRIBUTE_UNUSED)
187
{
188
  static const struct option xtra_long[] =
189
  {
190
    /* PE options */
191
    {"base-file", required_argument, NULL, OPTION_BASE_FILE},
192
    {"dll", no_argument, NULL, OPTION_DLL},
193
    {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
194
    {"heap", required_argument, NULL, OPTION_HEAP},
195
    {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
196
    {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
197
    {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
198
    {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
199
    {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
200
    {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
201
    {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
202
    {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
203
    {"stack", required_argument, NULL, OPTION_STACK},
204
    {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
205
    {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
206
#ifdef DLL_SUPPORT
207
    /* getopt allows abbreviations, so we do this to stop it
208
       from treating -o as an abbreviation for this option.  */
209
    {"output-def", required_argument, NULL, OPTION_OUT_DEF},
210
    {"output-def", required_argument, NULL, OPTION_OUT_DEF},
211
    {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL},
212
    {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS},
213
    {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
214
    {"kill-at", no_argument, NULL, OPTION_KILL_ATS},
215
    {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES},
216
    {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP},
217
    {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP},
218
    {"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME},
219
    {"warn-duplicate-exports", no_argument, NULL, OPTION_WARN_DUPLICATE_EXPORTS},
220
    /* getopt() allows abbreviations, so we do this to stop it from
221
       treating -c as an abbreviation for these --compat-implib.  */
222
    {"compat-implib", no_argument, NULL, OPTION_IMP_COMPAT},
223
    {"compat-implib", no_argument, NULL, OPTION_IMP_COMPAT},
224
    {"enable-auto-image-base", no_argument, NULL, OPTION_ENABLE_AUTO_IMAGE_BASE},
225
    {"disable-auto-image-base", no_argument, NULL, OPTION_DISABLE_AUTO_IMAGE_BASE},
226
    {"dll-search-prefix", required_argument, NULL, OPTION_DLL_SEARCH_PREFIX},
227
    {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
228
    {"enable-auto-import", no_argument, NULL, OPTION_DLL_ENABLE_AUTO_IMPORT},
229
    {"disable-auto-import", no_argument, NULL, OPTION_DLL_DISABLE_AUTO_IMPORT},
230
    {"enable-extra-pep-debug", no_argument, NULL, OPTION_ENABLE_EXTRA_PE_DEBUG},
231
    {"enable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC},
232
    {"disable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC},
233
#endif
234
    {NULL, no_argument, NULL, 0}
235
  };
236
 
237
  *longopts = xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
238
  memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
239
}
240
 
241
/* PE/WIN32; added routines to get the subsystem type, heap and/or stack
242
   parameters which may be input from the command line.  */
243
 
244
typedef struct
245
{
246
  void *ptr;
247
  int size;
248
  int value;
249
  char *symbol;
250
  int inited;
251
} definfo;
252
 
253
#define D(field,symbol,def)  {&pep.field,sizeof(pep.field), def, symbol,0}
254
 
255
static definfo init[] =
256
{
257
  /* imagebase must be first */
258
#define IMAGEBASEOFF 0
259
  D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
260
#define DLLOFF 1
261
  {&dll, sizeof(dll), 0, "__dll__", 0},
262
#define MSIMAGEBASEOFF  2
263
  D(ImageBase,"___ImageBase", NT_EXE_IMAGE_BASE),
264
  D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
265
  D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
266
  D(MajorOperatingSystemVersion,"__major_os_version__", 4),
267
  D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
268
  D(MajorImageVersion,"__major_image_version__", 0),
269
  D(MinorImageVersion,"__minor_image_version__", 0),
270
  D(MajorSubsystemVersion,"__major_subsystem_version__", 5),
271
  D(MinorSubsystemVersion,"__minor_subsystem_version__", 2),
272
  D(Subsystem,"__subsystem__", ${SUBSYSTEM}),
273
  D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x200000),
274
  D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
275
  D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
276
  D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
277
  D(LoaderFlags,"__loader_flags__", 0x0),
278
  { NULL, 0, 0, NULL, 0 }
279
};
280
 
281
 
282
static void
283
gld_${EMULATION_NAME}_list_options (FILE *file)
284
{
285
  fprintf (file, _("  --base_file              Generate a base file for relocatable DLLs\n"));
286
  fprintf (file, _("  --dll                              Set image base to the default for DLLs\n"));
287
  fprintf (file, _("  --file-alignment             Set file alignment\n"));
288
  fprintf (file, _("  --heap                       Set initial size of the heap\n"));
289
  fprintf (file, _("  --image-base 
Set start address of the executable\n"));
290
  fprintf (file, _("  --major-image-version      Set version number of the executable\n"));
291
  fprintf (file, _("  --major-os-version         Set minimum required OS version\n"));
292
  fprintf (file, _("  --major-subsystem-version  Set minimum required OS subsystem version\n"));
293
  fprintf (file, _("  --minor-image-version      Set revision number of the executable\n"));
294
  fprintf (file, _("  --minor-os-version         Set minimum required OS revision\n"));
295
  fprintf (file, _("  --minor-subsystem-version  Set minimum required OS subsystem revision\n"));
296
  fprintf (file, _("  --section-alignment          Set section alignment\n"));
297
  fprintf (file, _("  --stack                      Set size of the initial stack\n"));
298
  fprintf (file, _("  --subsystem [:]     Set required OS subsystem [& version]\n"));
299
  fprintf (file, _("  --support-old-code                 Support interworking with old code\n"));
300
#ifdef DLL_SUPPORT
301
  fprintf (file, _("  --add-stdcall-alias                Export symbols with and without @nn\n"));
302
  fprintf (file, _("  --disable-stdcall-fixup            Don't link _sym to _sym@nn\n"));
303
  fprintf (file, _("  --enable-stdcall-fixup             Link _sym to _sym@nn without warnings\n"));
304
  fprintf (file, _("  --exclude-symbols sym,sym,...      Exclude symbols from automatic export\n"));
305
  fprintf (file, _("  --exclude-libs lib,lib,...         Exclude libraries from automatic export\n"));
306
  fprintf (file, _("  --export-all-symbols               Automatically export all globals to DLL\n"));
307
  fprintf (file, _("  --kill-at                          Remove @nn from exported symbols\n"));
308
  fprintf (file, _("  --out-implib                 Generate import library\n"));
309
  fprintf (file, _("  --output-def                 Generate a .DEF file for the built DLL\n"));
310
  fprintf (file, _("  --warn-duplicate-exports           Warn about duplicate exports.\n"));
311
  fprintf (file, _("  --compat-implib                    Create backward compatible import libs;\n\
312
                                       create __imp_ as well.\n"));
313
  fprintf (file, _("  --enable-auto-image-base           Automatically choose image base for DLLs\n\
314
                                       unless user specifies one\n"));
315
  fprintf (file, _("  --disable-auto-image-base          Do not auto-choose image base. (default)\n"));
316
  fprintf (file, _("  --dll-search-prefix=       When linking dynamically to a dll without\n\
317
                                       an importlib, use .dll\n\
318
                                       in preference to lib.dll \n"));
319
  fprintf (file, _("  --enable-auto-import               Do sophistcated linking of _sym to\n\
320
                                       __imp_sym for DATA references\n"));
321
  fprintf (file, _("  --disable-auto-import              Do not auto-import DATA items from DLLs\n"));
322
  fprintf (file, _("  --enable-runtime-pseudo-reloc      Work around auto-import limitations by\n\
323
                                       adding pseudo-relocations resolved at\n\
324
                                       runtime.\n"));
325
  fprintf (file, _("  --disable-runtime-pseudo-reloc     Do not add runtime pseudo-relocations for\n\
326
                                       auto-imported DATA.\n"));
327
  fprintf (file, _("  --enable-extra-pep-debug            Enable verbose debug output when building\n\
328
                                       or linking to DLLs (esp. auto-import)\n"));
329
#endif
330
}
331
 
332
 
333
static void
334
set_pep_name (char *name, long val)
335
{
336
  int i;
337
 
338
  /* Find the name and set it.  */
339
  for (i = 0; init[i].ptr; i++)
340
    {
341
      if (strcmp (name, init[i].symbol) == 0)
342
        {
343
          init[i].value = val;
344
          init[i].inited = 1;
345
          if (strcmp (name,"__image_base__") == 0)
346
            set_pep_name ("___ImageBase", val);
347
          return;
348
        }
349
    }
350
  abort ();
351
}
352
 
353
 
354
static void
355
set_pep_subsystem (void)
356
{
357
  const char *sver;
358
  const char *entry;
359
  const char *initial_symbol_char;
360
  char *end;
361
  int len;
362
  int i;
363
  int subsystem;
364
  unsigned long temp_subsystem;
365
  static const struct
366
    {
367
      const char *name;
368
      const int value;
369
      const char *entry;
370
    }
371
  v[] =
372
    {
373
      { "native",  1, "NtProcessStartup" },
374
      { "windows", 2, "WinMainCRTStartup" },
375
      { "console", 3, "mainCRTStartup" },
376
      { "posix",   7, "__PosixProcessStartup"},
377
      { "wince",   9, "_WinMainCRTStartup" },
378
      { "xbox",   14, "mainCRTStartup" },
379
      { NULL, 0, NULL }
380
    };
381
  /* Entry point name for arbitrary subsystem numbers.  */
382
  static const char default_entry[] = "mainCRTStartup";
383
 
384
  /* Check for the presence of a version number.  */
385
  sver = strchr (optarg, ':');
386
  if (sver == NULL)
387
    len = strlen (optarg);
388
  else
389
    {
390
      len = sver - optarg;
391
      set_pep_name ("__major_subsystem_version__",
392
                    strtoul (sver + 1, &end, 0));
393
      if (*end == '.')
394
        set_pep_name ("__minor_subsystem_version__",
395
                      strtoul (end + 1, &end, 0));
396
      if (*end != '\0')
397
        einfo (_("%P: warning: bad version number in -subsystem option\n"));
398
    }
399
 
400
  /* Check for numeric subsystem.  */
401
  temp_subsystem = strtoul (optarg, & end, 0);
402
  if ((*end == ':' || *end == '\0') && (temp_subsystem < 65536))
403
    {
404
      /* Search list for a numeric match to use its entry point.  */
405
      for (i = 0; v[i].name; i++)
406
        if (v[i].value == (int) temp_subsystem)
407
          break;
408
 
409
      /* If no match, use the default.  */
410
      if (v[i].name != NULL)
411
        entry = v[i].entry;
412
      else
413
        entry = default_entry;
414
 
415
      /* Use this subsystem.  */
416
      subsystem = (int) temp_subsystem;
417
    }
418
  else
419
    {
420
      /* Search for subsystem by name.  */
421
      for (i = 0; v[i].name; i++)
422
        if (strncmp (optarg, v[i].name, len) == 0
423
            && v[i].name[len] == '\0')
424
          break;
425
 
426
      if (v[i].name == NULL)
427
        {
428
          einfo (_("%P%F: invalid subsystem type %s\n"), optarg);
429
          return;
430
        }
431
 
432
      entry = v[i].entry;
433
      subsystem = v[i].value;
434
    }
435
 
436
  set_pep_name ("__subsystem__", subsystem);
437
 
438
  initial_symbol_char = ${INITIAL_SYMBOL_CHAR};
439
  if (*initial_symbol_char != '\0')
440
    {
441
      char *alc_entry;
442
 
443
      /* lang_default_entry expects its argument to be permanently
444
         allocated, so we don't free this string.  */
445
      alc_entry = xmalloc (strlen (initial_symbol_char)
446
                           + strlen (entry)
447
                           + 1);
448
      strcpy (alc_entry, initial_symbol_char);
449
      strcat (alc_entry, entry);
450
      entry = alc_entry;
451
    }
452
 
453
  lang_default_entry (entry);
454
 
455
  return;
456
}
457
 
458
 
459
static void
460
set_pep_value (char *name)
461
{
462
  char *end;
463
 
464
  set_pep_name (name,  strtoul (optarg, &end, 0));
465
 
466
  if (end == optarg)
467
    einfo (_("%P%F: invalid hex number for PE parameter '%s'\n"), optarg);
468
 
469
  optarg = end;
470
}
471
 
472
 
473
static void
474
set_pep_stack_heap (char *resname, char *comname)
475
{
476
  set_pep_value (resname);
477
 
478
  if (*optarg == ',')
479
    {
480
      optarg++;
481
      set_pep_value (comname);
482
    }
483
  else if (*optarg)
484
    einfo (_("%P%F: strange hex info for PE parameter '%s'\n"), optarg);
485
}
486
 
487
 
488
static bfd_boolean
489
gld${EMULATION_NAME}_handle_option (int optc)
490
{
491
  switch (optc)
492
    {
493
    default:
494
      return FALSE;
495
 
496
    case OPTION_BASE_FILE:
497
      link_info.base_file = fopen (optarg, FOPEN_WB);
498
      if (link_info.base_file == NULL)
499
        {
500
          /* xgettext:c-format */
501
          fprintf (stderr, _("%s: Can't open base file %s\n"),
502
                   program_name, optarg);
503
          xexit (1);
504
        }
505
      break;
506
 
507
      /* PE options.  */
508
    case OPTION_HEAP:
509
      set_pep_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
510
      break;
511
    case OPTION_STACK:
512
      set_pep_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
513
      break;
514
    case OPTION_SUBSYSTEM:
515
      set_pep_subsystem ();
516
      break;
517
    case OPTION_MAJOR_OS_VERSION:
518
      set_pep_value ("__major_os_version__");
519
      break;
520
    case OPTION_MINOR_OS_VERSION:
521
      set_pep_value ("__minor_os_version__");
522
      break;
523
    case OPTION_MAJOR_SUBSYSTEM_VERSION:
524
      set_pep_value ("__major_subsystem_version__");
525
      break;
526
    case OPTION_MINOR_SUBSYSTEM_VERSION:
527
      set_pep_value ("__minor_subsystem_version__");
528
      break;
529
    case OPTION_MAJOR_IMAGE_VERSION:
530
      set_pep_value ("__major_image_version__");
531
      break;
532
    case OPTION_MINOR_IMAGE_VERSION:
533
      set_pep_value ("__minor_image_version__");
534
      break;
535
    case OPTION_FILE_ALIGNMENT:
536
      set_pep_value ("__file_alignment__");
537
      break;
538
    case OPTION_SECTION_ALIGNMENT:
539
      set_pep_value ("__section_alignment__");
540
      break;
541
    case OPTION_DLL:
542
      set_pep_name ("__dll__", 1);
543
      break;
544
    case OPTION_IMAGE_BASE:
545
      set_pep_value ("__image_base__");
546
      break;
547
    case OPTION_SUPPORT_OLD_CODE:
548
      support_old_code = 1;
549
      break;
550
#ifdef DLL_SUPPORT
551
    case OPTION_OUT_DEF:
552
      pep_out_def_filename = xstrdup (optarg);
553
      break;
554
    case OPTION_EXPORT_ALL:
555
      pep_dll_export_everything = 1;
556
      break;
557
    case OPTION_EXCLUDE_SYMBOLS:
558
      pep_dll_add_excludes (optarg, 0);
559
      break;
560
    case OPTION_EXCLUDE_LIBS:
561
      pep_dll_add_excludes (optarg, 1);
562
      break;
563
    case OPTION_KILL_ATS:
564
      pep_dll_kill_ats = 1;
565
      break;
566
    case OPTION_STDCALL_ALIASES:
567
      pep_dll_stdcall_aliases = 1;
568
      break;
569
    case OPTION_ENABLE_STDCALL_FIXUP:
570
      pep_enable_stdcall_fixup = 1;
571
      break;
572
    case OPTION_DISABLE_STDCALL_FIXUP:
573
      pep_enable_stdcall_fixup = 0;
574
      break;
575
    case OPTION_IMPLIB_FILENAME:
576
      pep_implib_filename = xstrdup (optarg);
577
      break;
578
    case OPTION_WARN_DUPLICATE_EXPORTS:
579
      pep_dll_warn_dup_exports = 1;
580
      break;
581
    case OPTION_IMP_COMPAT:
582
      pep_dll_compat_implib = 1;
583
      break;
584
    case OPTION_ENABLE_AUTO_IMAGE_BASE:
585
      pep_enable_auto_image_base = 1;
586
      break;
587
    case OPTION_DISABLE_AUTO_IMAGE_BASE:
588
      pep_enable_auto_image_base = 0;
589
      break;
590
    case OPTION_DLL_SEARCH_PREFIX:
591
      pep_dll_search_prefix = xstrdup (optarg);
592
      break;
593
    case OPTION_NO_DEFAULT_EXCLUDES:
594
      pep_dll_do_default_excludes = 0;
595
      break;
596
    case OPTION_DLL_ENABLE_AUTO_IMPORT:
597
      link_info.pei386_auto_import = 1;
598
      break;
599
    case OPTION_DLL_DISABLE_AUTO_IMPORT:
600
      link_info.pei386_auto_import = 0;
601
      break;
602
    case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC:
603
      link_info.pei386_runtime_pseudo_reloc = 1;
604
      break;
605
    case OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC:
606
      link_info.pei386_runtime_pseudo_reloc = 0;
607
      break;
608
    case OPTION_ENABLE_EXTRA_PE_DEBUG:
609
      pep_dll_extra_pe_debug = 1;
610
      break;
611
#endif
612
    }
613
  return TRUE;
614
}
615
 
616
 
617
#ifdef DLL_SUPPORT
618
static unsigned long
619
strhash (const char *str)
620
{
621
  const unsigned char *s;
622
  unsigned long hash;
623
  unsigned int c;
624
  unsigned int len;
625
 
626
  hash = 0;
627
  len = 0;
628
  s = (const unsigned char *) str;
629
  while ((c = *s++) != '\0')
630
    {
631
      hash += c + (c << 17);
632
      hash ^= hash >> 2;
633
      ++len;
634
    }
635
  hash += len + (len << 17);
636
  hash ^= hash >> 2;
637
 
638
  return hash;
639
}
640
 
641
/* Use the output file to create a image base for relocatable DLLs.  */
642
 
643
static unsigned long
644
compute_dll_image_base (const char *ofile)
645
{
646
  unsigned long hash = strhash (ofile);
647
  return 0x61300000 + ((hash << 16) & 0x0FFC0000);
648
}
649
#endif
650
 
651
/* Assign values to the special symbols before the linker script is
652
   read.  */
653
 
654
static void
655
gld_${EMULATION_NAME}_set_symbols (void)
656
{
657
  /* Run through and invent symbols for all the
658
     names and insert the defaults.  */
659
  int j;
660
  lang_statement_list_type *save;
661
 
662
  if (!init[IMAGEBASEOFF].inited)
663
    {
664
      if (link_info.relocatable)
665
        init[IMAGEBASEOFF].value = 0;
666
      else if (init[DLLOFF].value || (link_info.shared && !link_info.pie))
667
#ifdef DLL_SUPPORT
668
        init[IMAGEBASEOFF].value = (pep_enable_auto_image_base) ?
669
          compute_dll_image_base (output_filename) : NT_DLL_IMAGE_BASE;
670
#else
671
        init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE;
672
#endif
673
      else
674
        init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE;
675
        init[MSIMAGEBASEOFF].value = init[IMAGEBASEOFF].value;
676
    }
677
 
678
  /* Don't do any symbol assignments if this is a relocatable link.  */
679
  if (link_info.relocatable)
680
    return;
681
 
682
  /* Glue the assignments into the abs section.  */
683
  save = stat_ptr;
684
 
685
  stat_ptr = &(abs_output_section->children);
686
 
687
  for (j = 0; init[j].ptr; j++)
688
    {
689
      long val = init[j].value;
690
      lang_assignment_statement_type *rv;
691
      rv = lang_add_assignment (exp_assop ('=', init[j].symbol,
692
                                           exp_intop (val)));
693
      if (init[j].size == sizeof (short))
694
        *(short *) init[j].ptr = val;
695
      else if (init[j].size == sizeof (int))
696
        *(int *) init[j].ptr = val;
697
      else if (init[j].size == sizeof (long))
698
        *(long *) init[j].ptr = val;
699
      /* This might be a long long or other special type.  */
700
      else if (init[j].size == sizeof (bfd_vma))
701
        *(bfd_vma *) init[j].ptr = val;
702
      else      abort ();
703
      if (j == IMAGEBASEOFF)
704
        image_base_statement = rv;
705
    }
706
  /* Restore the pointer.  */
707
  stat_ptr = save;
708
 
709
  if (pep.FileAlignment > pep.SectionAlignment)
710
    {
711
      einfo (_("%P: warning, file alignment > section alignment.\n"));
712
    }
713
}
714
 
715
/* This is called after the linker script and the command line options
716
   have been read.  */
717
 
718
static void
719
gld_${EMULATION_NAME}_after_parse (void)
720
{
721
  /* The Windows libraries are designed for the linker to treat the
722
     entry point as an undefined symbol.  Otherwise, the .obj that
723
     defines mainCRTStartup is brought in because it is the first
724
     encountered in libc.lib and it has other symbols in it which will
725
     be pulled in by the link process.  To avoid this, we act as
726
     though the user specified -u with the entry point symbol.
727
 
728
     This function is called after the linker script and command line
729
     options have been read, so at this point we know the right entry
730
     point.  This function is called before the input files are
731
     opened, so registering the symbol as undefined will make a
732
     difference.  */
733
 
734
  if (! link_info.relocatable && entry_symbol.name != NULL)
735
    ldlang_add_undef (entry_symbol.name);
736
}
737
 
738
/* pep-dll.c directly accesses pep_data_import_dll,
739
   so it must be defined outside of #ifdef DLL_SUPPORT.
740
   Note - this variable is deliberately not initialised.
741
   This allows it to be treated as a common varaible, and only
742
   exist in one incarnation in a multiple target enabled linker.  */
743
char * pep_data_import_dll;
744
 
745
#ifdef DLL_SUPPORT
746
static struct bfd_link_hash_entry *pep_undef_found_sym;
747
 
748
static bfd_boolean
749
pep_undef_cdecl_match (struct bfd_link_hash_entry *h, void *inf)
750
{
751
  int sl;
752
  char *string = inf;
753
 
754
  sl = strlen (string);
755
  if (h->type == bfd_link_hash_defined
756
      && strncmp (h->root.string, string, sl) == 0
757
      && h->root.string[sl] == '@')
758
    {
759
      pep_undef_found_sym = h;
760
      return FALSE;
761
    }
762
  return TRUE;
763
}
764
 
765
static void
766
pep_fixup_stdcalls (void)
767
{
768
  static int gave_warning_message = 0;
769
  struct bfd_link_hash_entry *undef, *sym;
770
 
771
  if (pep_dll_extra_pe_debug)
772
    printf ("%s\n", __FUNCTION__);
773
 
774
  for (undef = link_info.hash->undefs; undef; undef=undef->u.undef.next)
775
    if (undef->type == bfd_link_hash_undefined)
776
      {
777
        char* at = strchr (undef->root.string, '@');
778
        int lead_at = (*undef->root.string == '@');
779
        /* For now, don't try to fixup fastcall symbols.  */
780
 
781
        if (at && !lead_at)
782
          {
783
            /* The symbol is a stdcall symbol, so let's look for a
784
               cdecl symbol with the same name and resolve to that.  */
785
            char *cname = xstrdup (undef->root.string /* + lead_at */);
786
            at = strchr (cname, '@');
787
            *at = 0;
788
            sym = bfd_link_hash_lookup (link_info.hash, cname, 0, 0, 1);
789
 
790
            if (sym && sym->type == bfd_link_hash_defined)
791
              {
792
                undef->type = bfd_link_hash_defined;
793
                undef->u.def.value = sym->u.def.value;
794
                undef->u.def.section = sym->u.def.section;
795
 
796
                if (pep_enable_stdcall_fixup == -1)
797
                  {
798
                    einfo (_("Warning: resolving %s by linking to %s\n"),
799
                           undef->root.string, cname);
800
                    if (! gave_warning_message)
801
                      {
802
                        gave_warning_message = 1;
803
                        einfo (_("Use --enable-stdcall-fixup to disable these warnings\n"));
804
                        einfo (_("Use --disable-stdcall-fixup to disable these fixups\n"));
805
                      }
806
                  }
807
              }
808
          }
809
        else
810
          {
811
            /* The symbol is a cdecl symbol, so we look for stdcall
812
               symbols - which means scanning the whole symbol table.  */
813
            pep_undef_found_sym = 0;
814
            bfd_link_hash_traverse (link_info.hash, pep_undef_cdecl_match,
815
                                    (char *) undef->root.string);
816
            sym = pep_undef_found_sym;
817
            if (sym)
818
              {
819
                undef->type = bfd_link_hash_defined;
820
                undef->u.def.value = sym->u.def.value;
821
                undef->u.def.section = sym->u.def.section;
822
 
823
                if (pep_enable_stdcall_fixup == -1)
824
                  {
825
                    einfo (_("Warning: resolving %s by linking to %s\n"),
826
                           undef->root.string, sym->root.string);
827
                    if (! gave_warning_message)
828
                      {
829
                        gave_warning_message = 1;
830
                        einfo (_("Use --enable-stdcall-fixup to disable these warnings\n"));
831
                        einfo (_("Use --disable-stdcall-fixup to disable these fixups\n"));
832
                      }
833
                  }
834
              }
835
          }
836
      }
837
}
838
 
839
static int
840
make_import_fixup (arelent *rel, asection *s)
841
{
842
  struct bfd_symbol *sym = *rel->sym_ptr_ptr;
843
  char addend[4];
844
 
845
  if (pep_dll_extra_pe_debug)
846
    printf ("arelent: %s@%#lx: add=%li\n", sym->name,
847
            (long) rel->address, (long) rel->addend);
848
 
849
  if (! bfd_get_section_contents (s->owner, s, addend, rel->address, sizeof (addend)))
850
    einfo (_("%C: Cannot get section contents - auto-import exception\n"),
851
           s->owner, s, rel->address);
852
 
853
  pep_create_import_fixup (rel, s, bfd_get_32 (s->owner, addend));
854
 
855
  return 1;
856
}
857
 
858
static void
859
pep_find_data_imports (void)
860
{
861
  struct bfd_link_hash_entry *undef, *sym;
862
 
863
  if (link_info.pei386_auto_import == 0)
864
    return;
865
 
866
  for (undef = link_info.hash->undefs; undef; undef=undef->u.undef.next)
867
    {
868
      if (undef->type == bfd_link_hash_undefined)
869
        {
870
          /* C++ symbols are *long*.  */
871
          char buf[4096];
872
 
873
          if (pep_dll_extra_pe_debug)
874
            printf ("%s:%s\n", __FUNCTION__, undef->root.string);
875
 
876
          sprintf (buf, "__imp_%s", undef->root.string);
877
 
878
          sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
879
 
880
          if (sym && sym->type == bfd_link_hash_defined)
881
            {
882
              bfd *b = sym->u.def.section->owner;
883
              asymbol **symbols;
884
              int nsyms, symsize, i;
885
 
886
              if (link_info.pei386_auto_import == -1)
887
                {
888
                  static bfd_boolean warned = FALSE;
889
 
890
                  info_msg (_("Info: resolving %s by linking to %s (auto-import)\n"),
891
                            undef->root.string, buf);
892
 
893
                  /* PR linker/4844.  */
894
                  if (! warned)
895
                    {
896
                      warned = TRUE;
897
                      einfo (_("%P: warning: auto-importing has been activated without --enable-auto-import specified on the command line.\n\
898
This should work unless it involves constant data structures referencing symbols from auto-imported DLLs."));
899
                    }
900
                }
901
 
902
              symsize = bfd_get_symtab_upper_bound (b);
903
              symbols = xmalloc (symsize);
904
              nsyms = bfd_canonicalize_symtab (b, symbols);
905
 
906
              for (i = 0; i < nsyms; i++)
907
                {
908
                  if (! CONST_STRNEQ (symbols[i]->name, "__head_"))
909
                    continue;
910
 
911
                  if (pep_dll_extra_pe_debug)
912
                    printf ("->%s\n", symbols[i]->name);
913
 
914
                  pep_data_import_dll = (char*) (symbols[i]->name +
915
                                                sizeof ("__head_") - 1);
916
                  break;
917
                }
918
 
919
              pep_walk_relocs_of_symbol (&link_info, undef->root.string,
920
                                        make_import_fixup);
921
 
922
              /* Let's differentiate it somehow from defined.  */
923
              undef->type = bfd_link_hash_defweak;
924
              /* We replace original name with __imp_ prefixed, this
925
                 1) may trash memory 2) leads to duplicate symbol generation.
926
                 Still, IMHO it's better than having name poluted.  */
927
              undef->root.string = sym->root.string;
928
              undef->u.def.value = sym->u.def.value;
929
              undef->u.def.section = sym->u.def.section;
930
            }
931
        }
932
    }
933
}
934
 
935
static bfd_boolean
936
pr_sym (struct bfd_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
937
{
938
  if (pep_dll_extra_pe_debug)
939
    printf ("+%s\n", h->string);
940
 
941
  return TRUE;
942
}
943
#endif /* DLL_SUPPORT */
944
 
945
 
946
static void
947
gld_${EMULATION_NAME}_after_open (void)
948
{
949
#ifdef DLL_SUPPORT
950
  if (pep_dll_extra_pe_debug)
951
    {
952
      bfd *a;
953
      struct bfd_link_hash_entry *sym;
954
 
955
      printf ("%s()\n", __FUNCTION__);
956
 
957
      for (sym = link_info.hash->undefs; sym; sym=sym->u.undef.next)
958
        printf ("-%s\n", sym->root.string);
959
      bfd_hash_traverse (&link_info.hash->table, pr_sym, NULL);
960
 
961
      for (a = link_info.input_bfds; a; a = a->link_next)
962
        printf ("*%s\n",a->filename);
963
    }
964
#endif
965
 
966
  /* Pass the wacky PE command line options into the output bfd.
967
     FIXME: This should be done via a function, rather than by
968
     including an internal BFD header.  */
969
 
970
  if (coff_data (link_info.output_bfd) == NULL
971
      || coff_data (link_info.output_bfd)->pe == 0)
972
    einfo (_("%F%P: cannot perform PE operations on non PE output file '%B'.\n"),
973
           link_info.output_bfd);
974
 
975
  pe_data (link_info.output_bfd)->pe_opthdr = pep;
976
  pe_data (link_info.output_bfd)->dll = init[DLLOFF].value;
977
  pe_data (link_info.output_bfd)->real_flags |= real_flags;
978
 
979
#ifdef DLL_SUPPORT
980
  if (pep_enable_stdcall_fixup) /* -1=warn or 1=disable */
981
    pep_fixup_stdcalls ();
982
 
983
  pep_process_import_defs (link_info.output_bfd, &link_info);
984
 
985
  pep_find_data_imports ();
986
 
987
#ifndef TARGET_IS_i386pep
988
  if (link_info.shared)
989
#else
990
  if (!link_info.relocatable)
991
#endif
992
    pep_dll_build_sections (link_info.output_bfd, &link_info);
993
 
994
#ifndef TARGET_IS_i386pep
995
  else
996
    pep_exe_build_sections (link_info.output_bfd, &link_info);
997
#endif
998
#endif /* DLL_SUPPORT */
999
 
1000
  {
1001
    /* This next chunk of code tries to detect the case where you have
1002
       two import libraries for the same DLL (specifically,
1003
       symbolically linking libm.a and libc.a in cygwin to
1004
       libcygwin.a).  In those cases, it's possible for function
1005
       thunks from the second implib to be used but without the
1006
       head/tail objects, causing an improper import table.  We detect
1007
       those cases and rename the "other" import libraries to match
1008
       the one the head/tail come from, so that the linker will sort
1009
       things nicely and produce a valid import table.  */
1010
 
1011
    LANG_FOR_EACH_INPUT_STATEMENT (is)
1012
      {
1013
        if (is->the_bfd->my_archive)
1014
          {
1015
            int idata2 = 0, reloc_count=0, is_imp = 0;
1016
            asection *sec;
1017
 
1018
            /* See if this is an import library thunk.  */
1019
            for (sec = is->the_bfd->sections; sec; sec = sec->next)
1020
              {
1021
                if (strcmp (sec->name, ".idata\$2") == 0)
1022
                  idata2 = 1;
1023
                if (CONST_STRNEQ (sec->name, ".idata\$"))
1024
                  is_imp = 1;
1025
                reloc_count += sec->reloc_count;
1026
              }
1027
 
1028
            if (is_imp && !idata2 && reloc_count)
1029
              {
1030
                /* It is, look for the reference to head and see if it's
1031
                   from our own library.  */
1032
                for (sec = is->the_bfd->sections; sec; sec = sec->next)
1033
                  {
1034
                    int i;
1035
                    long symsize;
1036
                    long relsize;
1037
                    asymbol **symbols;
1038
                    arelent **relocs;
1039
                    int nrelocs;
1040
 
1041
                    symsize = bfd_get_symtab_upper_bound (is->the_bfd);
1042
                    if (symsize < 1)
1043
                      break;
1044
                    relsize = bfd_get_reloc_upper_bound (is->the_bfd, sec);
1045
                    if (relsize < 1)
1046
                      break;
1047
 
1048
                    symbols = xmalloc (symsize);
1049
                    symsize = bfd_canonicalize_symtab (is->the_bfd, symbols);
1050
                    if (symsize < 0)
1051
                      {
1052
                        einfo ("%X%P: unable to process symbols: %E");
1053
                        return;
1054
                      }
1055
 
1056
                    relocs = xmalloc ((size_t) relsize);
1057
                    nrelocs = bfd_canonicalize_reloc (is->the_bfd, sec,
1058
                                                      relocs, symbols);
1059
                    if (nrelocs < 0)
1060
                      {
1061
                        free (relocs);
1062
                        einfo ("%X%P: unable to process relocs: %E");
1063
                        return;
1064
                      }
1065
 
1066
                    for (i = 0; i < nrelocs; i++)
1067
                      {
1068
                        struct bfd_symbol *s;
1069
                        struct bfd_link_hash_entry * blhe;
1070
                        char *other_bfd_filename;
1071
                        char *n;
1072
 
1073
                        s = (relocs[i]->sym_ptr_ptr)[0];
1074
 
1075
                        if (s->flags & BSF_LOCAL)
1076
                          continue;
1077
 
1078
                        /* Thunk section with reloc to another bfd.  */
1079
                        blhe = bfd_link_hash_lookup (link_info.hash,
1080
                                                     s->name,
1081
                                                     FALSE, FALSE, TRUE);
1082
 
1083
                        if (blhe == NULL
1084
                            || blhe->type != bfd_link_hash_defined)
1085
                          continue;
1086
 
1087
                        other_bfd_filename
1088
                          = blhe->u.def.section->owner->my_archive
1089
                            ? bfd_get_filename (blhe->u.def.section->owner->my_archive)
1090
                            : bfd_get_filename (blhe->u.def.section->owner);
1091
 
1092
                        if (strcmp (bfd_get_filename (is->the_bfd->my_archive),
1093
                                    other_bfd_filename) == 0)
1094
                          continue;
1095
 
1096
                        /* Rename this implib to match the other one.  */
1097
                        n = xmalloc (strlen (other_bfd_filename) + 1);
1098
                        strcpy (n, other_bfd_filename);
1099
                        is->the_bfd->my_archive->filename = n;
1100
                      }
1101
 
1102
                    free (relocs);
1103
                    /* Note - we do not free the symbols,
1104
                       they are now cached in the BFD.  */
1105
                  }
1106
              }
1107
          }
1108
      }
1109
  }
1110
 
1111
  {
1112
    int is_ms_arch = 0;
1113
    bfd *cur_arch = 0;
1114
    lang_input_statement_type *is2;
1115
    lang_input_statement_type *is3;
1116
 
1117
    /* Careful - this is a shell script.  Watch those dollar signs! */
1118
    /* Microsoft import libraries have every member named the same,
1119
       and not in the right order for us to link them correctly.  We
1120
       must detect these and rename the members so that they'll link
1121
       correctly.  There are three types of objects: the head, the
1122
       thunks, and the sentinel(s).  The head is easy; it's the one
1123
       with idata2.  We assume that the sentinels won't have relocs,
1124
       and the thunks will.  It's easier than checking the symbol
1125
       table for external references.  */
1126
    LANG_FOR_EACH_INPUT_STATEMENT (is)
1127
      {
1128
        if (is->the_bfd->my_archive)
1129
          {
1130
            char *pnt;
1131
            bfd *arch = is->the_bfd->my_archive;
1132
 
1133
            if (cur_arch != arch)
1134
              {
1135
                cur_arch = arch;
1136
                is_ms_arch = 1;
1137
 
1138
                for (is3 = is;
1139
                     is3 && is3->the_bfd->my_archive == arch;
1140
                     is3 = (lang_input_statement_type *) is3->next)
1141
                  {
1142
                    /* A MS dynamic import library can also contain static
1143
                       members, so look for the first element with a .dll
1144
                       extension, and use that for the remainder of the
1145
                       comparisons.  */
1146
                    pnt = strrchr (is3->the_bfd->filename, '.');
1147
                    if (pnt != NULL && strcmp (pnt, ".dll") == 0)
1148
                      break;
1149
                  }
1150
 
1151
                if (is3 == NULL)
1152
                  is_ms_arch = 0;
1153
                else
1154
                  {
1155
                    /* OK, found one.  Now look to see if the remaining
1156
                       (dynamic import) members use the same name.  */
1157
                    for (is2 = is;
1158
                         is2 && is2->the_bfd->my_archive == arch;
1159
                         is2 = (lang_input_statement_type *) is2->next)
1160
                      {
1161
                        /* Skip static members, ie anything with a .obj
1162
                           extension.  */
1163
                        pnt = strrchr (is2->the_bfd->filename, '.');
1164
                        if (pnt != NULL && strcmp (pnt, ".obj") == 0)
1165
                          continue;
1166
 
1167
                        if (strcmp (is3->the_bfd->filename,
1168
                                    is2->the_bfd->filename))
1169
                          {
1170
                            is_ms_arch = 0;
1171
                            break;
1172
                          }
1173
                      }
1174
                  }
1175
              }
1176
 
1177
            /* This fragment might have come from an .obj file in a Microsoft
1178
               import, and not an actual import record. If this is the case,
1179
               then leave the filename alone.  */
1180
            pnt = strrchr (is->the_bfd->filename, '.');
1181
 
1182
            if (is_ms_arch && (strcmp (pnt, ".dll") == 0))
1183
              {
1184
                int idata2 = 0, reloc_count=0;
1185
                asection *sec;
1186
                char *new_name, seq;
1187
 
1188
                for (sec = is->the_bfd->sections; sec; sec = sec->next)
1189
                  {
1190
                    if (strcmp (sec->name, ".idata\$2") == 0)
1191
                      idata2 = 1;
1192
                    reloc_count += sec->reloc_count;
1193
                  }
1194
 
1195
                if (idata2) /* .idata2 is the TOC */
1196
                  seq = 'a';
1197
                else if (reloc_count > 0) /* thunks */
1198
                  seq = 'b';
1199
                else /* sentinel */
1200
                  seq = 'c';
1201
 
1202
                new_name = xmalloc (strlen (is->the_bfd->filename) + 3);
1203
                sprintf (new_name, "%s.%c", is->the_bfd->filename, seq);
1204
                is->the_bfd->filename = new_name;
1205
 
1206
                new_name = xmalloc (strlen (is->filename) + 3);
1207
                sprintf (new_name, "%s.%c", is->filename, seq);
1208
                is->filename = new_name;
1209
              }
1210
          }
1211
      }
1212
  }
1213
}
1214
 
1215
static void
1216
gld_${EMULATION_NAME}_before_allocation (void)
1217
{
1218
  before_allocation_default ();
1219
}
1220
 
1221
#ifdef DLL_SUPPORT
1222
/* This is called when an input file isn't recognized as a BFD.  We
1223
   check here for .DEF files and pull them in automatically.  */
1224
 
1225
static int
1226
saw_option (char *option)
1227
{
1228
  int i;
1229
 
1230
  for (i = 0; init[i].ptr; i++)
1231
    if (strcmp (init[i].symbol, option) == 0)
1232
      return init[i].inited;
1233
  return 0;
1234
}
1235
#endif /* DLL_SUPPORT */
1236
 
1237
static bfd_boolean
1238
gld_${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry ATTRIBUTE_UNUSED)
1239
{
1240
#ifdef DLL_SUPPORT
1241
  const char *ext = entry->filename + strlen (entry->filename) - 4;
1242
 
1243
  if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0)
1244
    {
1245
      pep_def_file = def_file_parse (entry->filename, pep_def_file);
1246
 
1247
      if (pep_def_file)
1248
        {
1249
          int i, buflen=0, len;
1250
          char *buf;
1251
 
1252
          for (i = 0; i < pep_def_file->num_exports; i++)
1253
            {
1254
              len = strlen (pep_def_file->exports[i].internal_name);
1255
              if (buflen < len + 2)
1256
                buflen = len + 2;
1257
            }
1258
 
1259
          buf = xmalloc (buflen);
1260
 
1261
          for (i = 0; i < pep_def_file->num_exports; i++)
1262
            {
1263
              struct bfd_link_hash_entry *h;
1264
 
1265
              sprintf (buf, "_%s", pep_def_file->exports[i].internal_name);
1266
 
1267
              h = bfd_link_hash_lookup (link_info.hash, buf, TRUE, TRUE, TRUE);
1268
              if (h == (struct bfd_link_hash_entry *) NULL)
1269
                einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
1270
              if (h->type == bfd_link_hash_new)
1271
                {
1272
                  h->type = bfd_link_hash_undefined;
1273
                  h->u.undef.abfd = NULL;
1274
                  bfd_link_add_undef (link_info.hash, h);
1275
                }
1276
            }
1277
          free (buf);
1278
 
1279
          /* def_file_print (stdout, pep_def_file); */
1280
          if (pep_def_file->is_dll == 1)
1281
            link_info.shared = 1;
1282
 
1283
          if (pep_def_file->base_address != (bfd_vma)(-1))
1284
            {
1285
              pep.ImageBase
1286
                = pe_data (link_info.output_bfd)->pe_opthdr.ImageBase
1287
                = init[IMAGEBASEOFF].value
1288
                = pep_def_file->base_address;
1289
              init[IMAGEBASEOFF].inited = 1;
1290
              if (image_base_statement)
1291
                image_base_statement->exp = exp_assop ('=', "__image_base__",
1292
                                                       exp_intop (pep.ImageBase));
1293
            }
1294
 
1295
          if (pep_def_file->stack_reserve != -1
1296
              && ! saw_option ("__size_of_stack_reserve__"))
1297
            {
1298
              pep.SizeOfStackReserve = pep_def_file->stack_reserve;
1299
              if (pep_def_file->stack_commit != -1)
1300
                pep.SizeOfStackCommit = pep_def_file->stack_commit;
1301
            }
1302
          if (pep_def_file->heap_reserve != -1
1303
              && ! saw_option ("__size_of_heap_reserve__"))
1304
            {
1305
              pep.SizeOfHeapReserve = pep_def_file->heap_reserve;
1306
              if (pep_def_file->heap_commit != -1)
1307
                pep.SizeOfHeapCommit = pep_def_file->heap_commit;
1308
            }
1309
          return TRUE;
1310
        }
1311
    }
1312
#endif
1313
  return FALSE;
1314
}
1315
 
1316
static bfd_boolean
1317
gld_${EMULATION_NAME}_recognized_file (lang_input_statement_type *entry ATTRIBUTE_UNUSED)
1318
{
1319
#ifdef DLL_SUPPORT
1320
#ifdef TARGET_IS_i386pep
1321
  pep_dll_id_target ("pei-x86-64");
1322
#endif
1323
  if (pep_bfd_is_dll (entry->the_bfd))
1324
    return pep_implied_import_dll (entry->filename);
1325
#endif
1326
  return FALSE;
1327
}
1328
 
1329
static void
1330
gld_${EMULATION_NAME}_finish (void)
1331
{
1332
  finish_default ();
1333
 
1334
#ifdef DLL_SUPPORT
1335
  if (link_info.shared
1336
      || (!link_info.relocatable && pep_def_file->num_exports != 0))
1337
    {
1338
      pep_dll_fill_sections (link_info.output_bfd, &link_info);
1339
      if (pep_implib_filename)
1340
        pep_dll_generate_implib (pep_def_file, pep_implib_filename);
1341
    }
1342
 
1343
  if (pep_out_def_filename)
1344
    pep_dll_generate_def_file (pep_out_def_filename);
1345
#endif /* DLL_SUPPORT */
1346
 
1347
  /* I don't know where .idata gets set as code, but it shouldn't be.  */
1348
  {
1349
    asection *asec = bfd_get_section_by_name (link_info.output_bfd, ".idata");
1350
 
1351
    if (asec)
1352
      {
1353
        asec->flags &= ~SEC_CODE;
1354
        asec->flags |= SEC_DATA;
1355
      }
1356
  }
1357
}
1358
 
1359
 
1360
/* Place an orphan section.
1361
 
1362
   We use this to put sections in a reasonable place in the file, and
1363
   to ensure that they are aligned as required.
1364
 
1365
   We handle grouped sections here as well.  A section named .foo$nn
1366
   goes into the output section .foo.  All grouped sections are sorted
1367
   by name.
1368
 
1369
   Grouped sections for the default sections are handled by the
1370
   default linker script using wildcards, and are sorted by
1371
   sort_sections.  */
1372
 
1373
static bfd_boolean
1374
gld_${EMULATION_NAME}_place_orphan (asection *s)
1375
{
1376
  const char *secname;
1377
  const char *orig_secname;
1378
  char *dollar = NULL;
1379
  lang_output_section_statement_type *os;
1380
  lang_statement_list_type add_child;
1381
 
1382
  secname = bfd_get_section_name (s->owner, s);
1383
 
1384
  /* Look through the script to see where to place this section.  */
1385
  orig_secname = secname;
1386
  if (!link_info.relocatable
1387
      && (dollar = strchr (secname, '$')) != NULL)
1388
    {
1389
      size_t len = dollar - orig_secname;
1390
      char *newname = xmalloc (len + 1);
1391
      memcpy (newname, orig_secname, len);
1392
      newname[len] = '\0';
1393
      secname = newname;
1394
    }
1395
 
1396
  os = lang_output_section_find (secname);
1397
 
1398
  lang_list_init (&add_child);
1399
 
1400
  if (os != NULL
1401
      && (os->bfd_section == NULL
1402
          || os->bfd_section->flags == 0
1403
          || ((s->flags ^ os->bfd_section->flags)
1404
              & (SEC_LOAD | SEC_ALLOC)) == 0))
1405
    {
1406
      /* We already have an output section statement with this
1407
         name, and its bfd section, if any, has compatible flags.
1408
         If the section already exists but does not have any flags set,
1409
         then it has been created by the linker, probably as a result of
1410
         a --section-start command line switch.  */
1411
      lang_add_section (&add_child, s, os);
1412
    }
1413
  else
1414
    {
1415
      static struct orphan_save hold[] =
1416
        {
1417
          { ".text",
1418
            SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
1419
            0, 0, 0, 0 },
1420
          { ".rdata",
1421
            SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
1422
            0, 0, 0, 0 },
1423
          { ".data",
1424
            SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA,
1425
            0, 0, 0, 0 },
1426
          { ".bss",
1427
            SEC_ALLOC,
1428
            0, 0, 0, 0 }
1429
        };
1430
      enum orphan_save_index
1431
        {
1432
          orphan_text = 0,
1433
          orphan_rodata,
1434
          orphan_data,
1435
          orphan_bss
1436
        };
1437
      static int orphan_init_done = 0;
1438
      struct orphan_save *place;
1439
      lang_output_section_statement_type *after;
1440
      etree_type *address;
1441
 
1442
      if (!orphan_init_done)
1443
        {
1444
          struct orphan_save *ho;
1445
          for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
1446
            if (ho->name != NULL)
1447
              {
1448
                ho->os = lang_output_section_find (ho->name);
1449
                if (ho->os != NULL && ho->os->flags == 0)
1450
                  ho->os->flags = ho->flags;
1451
              }
1452
          orphan_init_done = 1;
1453
        }
1454
 
1455
      /* Try to put the new output section in a reasonable place based
1456
         on the section name and section flags.  */
1457
 
1458
      place = NULL;
1459
      if ((s->flags & SEC_ALLOC) == 0)
1460
        ;
1461
      else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
1462
        place = &hold[orphan_bss];
1463
      else if ((s->flags & SEC_READONLY) == 0)
1464
        place = &hold[orphan_data];
1465
      else if ((s->flags & SEC_CODE) == 0)
1466
        place = &hold[orphan_rodata];
1467
      else
1468
        place = &hold[orphan_text];
1469
 
1470
      after = NULL;
1471
      if (place != NULL)
1472
        {
1473
          if (place->os == NULL)
1474
            place->os = lang_output_section_find (place->name);
1475
          after = place->os;
1476
          if (after == NULL)
1477
            after = lang_output_section_find_by_flags (s, &place->os, NULL);
1478
          if (after == NULL)
1479
            /* *ABS* is always the first output section statement.  */
1480
            after = (&lang_output_section_statement.head
1481
                     ->output_section_statement);
1482
        }
1483
 
1484
      /* Choose a unique name for the section.  This will be needed if the
1485
         same section name appears in the input file with different
1486
         loadable or allocatable characteristics.  */
1487
      if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL)
1488
        {
1489
          static int count = 1;
1490
          secname = bfd_get_unique_section_name (link_info.output_bfd,
1491
                                                 secname, &count);
1492
          if (secname == NULL)
1493
            einfo ("%F%P: place_orphan failed: %E\n");
1494
        }
1495
 
1496
      /* All sections in an executable must be aligned to a page boundary.  */
1497
      address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
1498
      os = lang_insert_orphan (s, secname, after, place, address, &add_child);
1499
    }
1500
 
1501
  {
1502
    lang_statement_union_type **pl = &os->children.head;
1503
 
1504
    if (dollar != NULL)
1505
      {
1506
        bfd_boolean found_dollar;
1507
 
1508
        /* The section name has a '$'.  Sort it with the other '$'
1509
           sections.  */
1510
        found_dollar = FALSE;
1511
        for ( ; *pl != NULL; pl = &(*pl)->header.next)
1512
          {
1513
            lang_input_section_type *ls;
1514
            const char *lname;
1515
 
1516
            if ((*pl)->header.type != lang_input_section_enum)
1517
              continue;
1518
 
1519
            ls = &(*pl)->input_section;
1520
 
1521
            lname = bfd_get_section_name (ls->section->owner, ls->section);
1522
            if (strchr (lname, '$') == NULL)
1523
              {
1524
                if (found_dollar)
1525
                  break;
1526
              }
1527
            else
1528
              {
1529
                found_dollar = TRUE;
1530
                if (strcmp (orig_secname, lname) < 0)
1531
                  break;
1532
              }
1533
          }
1534
      }
1535
 
1536
    if (add_child.head != NULL)
1537
      {
1538
        add_child.head->header.next = *pl;
1539
        *pl = add_child.head;
1540
      }
1541
  }
1542
 
1543
  return TRUE;
1544
}
1545
 
1546
static bfd_boolean
1547
gld_${EMULATION_NAME}_open_dynamic_archive
1548
  (const char *arch ATTRIBUTE_UNUSED,
1549
   search_dirs_type *search,
1550
   lang_input_statement_type *entry)
1551
{
1552
  static const struct
1553
    {
1554
      const char * format;
1555
      bfd_boolean use_prefix;
1556
    }
1557
  libname_fmt [] =
1558
    {
1559
      /* Preferred explicit import library for dll's.  */
1560
      { "lib%s.dll.a", FALSE },
1561
      /* Alternate explicit import library for dll's.  */
1562
      { "%s.dll.a", FALSE },
1563
      /* "libfoo.a" could be either an import lib or a static lib.
1564
          For backwards compatibility, libfoo.a needs to precede
1565
          libfoo.dll and foo.dll in the search.  */
1566
      { "lib%s.a", FALSE },
1567
      /* The 'native' spelling of an import lib name is "foo.lib".  */
1568
      { "%s.lib", FALSE },
1569
#ifdef DLL_SUPPORT
1570
      /* Try "foo.dll" (preferred dll name, if specified).  */
1571
      { "%s%s.dll", TRUE },
1572
#endif
1573
      /* Try "libfoo.dll" (default preferred dll name).  */
1574
      { "lib%s.dll", FALSE },
1575
      /* Finally try 'native' dll name "foo.dll".  */
1576
      {  "%s.dll", FALSE },
1577
      /* Note: If adding more formats to this table, make sure to check to
1578
         see if their length is longer than libname_fmt[0].format, and if
1579
         so, update the call to xmalloc() below.  */
1580
      { NULL, FALSE }
1581
    };
1582
  static unsigned int format_max_len = 0;
1583
  const char * filename;
1584
  char * full_string;
1585
  char * base_string;
1586
  unsigned int i;
1587
 
1588
 
1589
  if (! entry->is_archive)
1590
    return FALSE;
1591
 
1592
  filename = entry->filename;
1593
 
1594
  if (format_max_len == 0)
1595
    /* We need to allow space in the memory that we are going to allocate
1596
       for the characters in the format string.  Since the format array is
1597
       static we only need to calculate this information once.  In theory
1598
       this value could also be computed statically, but this introduces
1599
       the possibility for a discrepancy and hence a possible memory
1600
       corruption.  The lengths we compute here will be too long because
1601
       they will include any formating characters (%s) in the strings, but
1602
       this will not matter.  */
1603
    for (i = 0; libname_fmt[i].format; i++)
1604
      if (format_max_len < strlen (libname_fmt[i].format))
1605
        format_max_len = strlen (libname_fmt[i].format);
1606
 
1607
  full_string = xmalloc (strlen (search->name)
1608
                         + strlen (filename)
1609
                         + format_max_len
1610
#ifdef DLL_SUPPORT
1611
                         + (pep_dll_search_prefix
1612
                            ? strlen (pep_dll_search_prefix) : 0)
1613
#endif
1614
                         /* Allow for the terminating NUL and for the path
1615
                            separator character that is inserted between
1616
                            search->name and the start of the format string.  */
1617
                         + 2);
1618
 
1619
  sprintf (full_string, "%s/", search->name);
1620
  base_string = full_string + strlen (full_string);
1621
 
1622
  for (i = 0; libname_fmt[i].format; i++)
1623
    {
1624
#ifdef DLL_SUPPORT
1625
      if (libname_fmt[i].use_prefix)
1626
        {
1627
          if (!pep_dll_search_prefix)
1628
            continue;
1629
          sprintf (base_string, libname_fmt[i].format, pep_dll_search_prefix, filename);
1630
        }
1631
      else
1632
#endif
1633
        sprintf (base_string, libname_fmt[i].format, filename);
1634
 
1635
      if (ldfile_try_open_bfd (full_string, entry))
1636
        break;
1637
    }
1638
 
1639
  if (!libname_fmt[i].format)
1640
    {
1641
      free (full_string);
1642
      return FALSE;
1643
    }
1644
 
1645
  entry->filename = full_string;
1646
 
1647
  return TRUE;
1648
}
1649
 
1650
static int
1651
gld_${EMULATION_NAME}_find_potential_libraries
1652
  (char *name, lang_input_statement_type *entry)
1653
{
1654
  return ldfile_open_file_search (name, entry, "", ".lib");
1655
}
1656
 
1657
static char *
1658
gld_${EMULATION_NAME}_get_script (int *isfile)
1659
EOF
1660
# Scripts compiled in.
1661
# sed commands to quote an ld script as a C string.
1662
sc="-f stringify.sed"
1663
 
1664
fragment <
1665
{
1666
  *isfile = 0;
1667
 
1668
  if (link_info.relocatable && config.build_constructors)
1669
    return
1670
EOF
1671
sed $sc ldscripts/${EMULATION_NAME}.xu                  >> e${EMULATION_NAME}.c
1672
echo '  ; else if (link_info.relocatable) return'       >> e${EMULATION_NAME}.c
1673
sed $sc ldscripts/${EMULATION_NAME}.xr                  >> e${EMULATION_NAME}.c
1674
echo '  ; else if (!config.text_read_only) return'      >> e${EMULATION_NAME}.c
1675
sed $sc ldscripts/${EMULATION_NAME}.xbn                 >> e${EMULATION_NAME}.c
1676
echo '  ; else if (!config.magic_demand_paged) return'  >> e${EMULATION_NAME}.c
1677
sed $sc ldscripts/${EMULATION_NAME}.xn                  >> e${EMULATION_NAME}.c
1678
if test -n "$GENERATE_AUTO_IMPORT_SCRIPT" ; then
1679
echo '  ; else if (link_info.pei386_auto_import == 1) return'   >> e${EMULATION_NAME}.c
1680
sed $sc ldscripts/${EMULATION_NAME}.xa                  >> e${EMULATION_NAME}.c
1681
fi
1682
echo '  ; else return'                                  >> e${EMULATION_NAME}.c
1683
sed $sc ldscripts/${EMULATION_NAME}.x                   >> e${EMULATION_NAME}.c
1684
echo '; }'                                              >> e${EMULATION_NAME}.c
1685
 
1686
fragment <
1687
 
1688
 
1689
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
1690
{
1691
  gld_${EMULATION_NAME}_before_parse,
1692
  syslib_default,
1693
  hll_default,
1694
  gld_${EMULATION_NAME}_after_parse,
1695
  gld_${EMULATION_NAME}_after_open,
1696
  after_allocation_default,
1697
  set_output_arch_default,
1698
  ldemul_default_target,
1699
  gld_${EMULATION_NAME}_before_allocation,
1700
  gld_${EMULATION_NAME}_get_script,
1701
  "${EMULATION_NAME}",
1702
  "${OUTPUT_FORMAT}",
1703
  gld_${EMULATION_NAME}_finish,
1704
  NULL, /* Create output section statements.  */
1705
  gld_${EMULATION_NAME}_open_dynamic_archive,
1706
  gld_${EMULATION_NAME}_place_orphan,
1707
  gld_${EMULATION_NAME}_set_symbols,
1708
  NULL, /* parse_args */
1709
  gld${EMULATION_NAME}_add_options,
1710
  gld${EMULATION_NAME}_handle_option,
1711
  gld_${EMULATION_NAME}_unrecognized_file,
1712
  gld_${EMULATION_NAME}_list_options,
1713
  gld_${EMULATION_NAME}_recognized_file,
1714
  gld_${EMULATION_NAME}_find_potential_libraries,
1715
  NULL  /* new_vers_pattern.  */
1716
};
1717
EOF

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.