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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [i386/] [winnt.c] - Blame information for rev 316

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

Line No. Rev Author Line
1 282 jeremybenn
/* Subroutines for insn-output.c for Windows NT.
2
   Contributed by Douglas Rupp (drupp@cs.washington.edu)
3
   Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4
   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "rtl.h"
27
#include "regs.h"
28
#include "hard-reg-set.h"
29
#include "output.h"
30
#include "tree.h"
31
#include "flags.h"
32
#include "tm_p.h"
33
#include "toplev.h"
34
#include "hashtab.h"
35
#include "langhooks.h"
36
#include "ggc.h"
37
#include "target.h"
38
#include "lto-streamer.h"
39
 
40
/* i386/PE specific attribute support.
41
 
42
   i386/PE has two new attributes:
43
   dllexport - for exporting a function/variable that will live in a dll
44
   dllimport - for importing a function/variable from a dll
45
 
46
   Microsoft allows multiple declspecs in one __declspec, separating
47
   them with spaces.  We do NOT support this.  Instead, use __declspec
48
   multiple times.
49
*/
50
 
51
/* Handle a "shared" attribute;
52
   arguments as in struct attribute_spec.handler.  */
53
tree
54
ix86_handle_shared_attribute (tree *node, tree name,
55
                              tree args ATTRIBUTE_UNUSED,
56
                              int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
57
{
58
  if (TREE_CODE (*node) != VAR_DECL)
59
    {
60
      warning (OPT_Wattributes, "%qE attribute only applies to variables",
61
               name);
62
      *no_add_attrs = true;
63
    }
64
 
65
  return NULL_TREE;
66
}
67
 
68
/* Handle a "selectany" attribute;
69
   arguments as in struct attribute_spec.handler.  */
70
tree
71
ix86_handle_selectany_attribute (tree *node, tree name,
72
                                 tree args ATTRIBUTE_UNUSED,
73
                                 int flags ATTRIBUTE_UNUSED,
74
                                 bool *no_add_attrs)
75
{
76
  /* The attribute applies only to objects that are initialized and have
77
     external linkage.  However, we may not know about initialization
78
     until the language frontend has processed the decl. We'll check for
79
     initialization later in encode_section_info.  */
80
  if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node))
81
    {
82
      error ("%qE attribute applies only to initialized variables"
83
             " with external linkage", name);
84
      *no_add_attrs = true;
85
    }
86
 
87
  return NULL_TREE;
88
}
89
 
90
 
91
/* Return the type that we should use to determine if DECL is
92
   imported or exported.  */
93
 
94
static tree
95
associated_type (tree decl)
96
{
97
  return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
98
          ?  DECL_CONTEXT (decl) : NULL_TREE);
99
}
100
 
101
/* Return true if DECL should be a dllexport'd object.  */
102
 
103
static bool
104
i386_pe_determine_dllexport_p (tree decl)
105
{
106
  if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
107
    return false;
108
 
109
  /* Don't export local clones of dllexports.  */
110
  if (!TREE_PUBLIC (decl))
111
    return false;
112
 
113
  if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
114
    return true;
115
 
116
  return false;
117
}
118
 
119
/* Return true if DECL should be a dllimport'd object.  */
120
 
121
static bool
122
i386_pe_determine_dllimport_p (tree decl)
123
{
124
  tree assoc;
125
 
126
  if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
127
    return false;
128
 
129
  if (DECL_DLLIMPORT_P (decl))
130
    return true;
131
 
132
  /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
133
     by  targetm.cxx.adjust_class_at_definition.  Check again to emit
134
     error message if the class attribute has been overridden by an
135
     out-of-class definition of static data.  */
136
  assoc = associated_type (decl);
137
  if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc))
138
      && TREE_CODE (decl) == VAR_DECL
139
      && TREE_STATIC (decl) && TREE_PUBLIC (decl)
140
      && !DECL_EXTERNAL (decl)
141
      /* vtable's are linkonce constants, so defining a vtable is not
142
         an error as long as we don't try to import it too.  */
143
      && !DECL_VIRTUAL_P (decl))
144
        error ("definition of static data member %q+D of "
145
               "dllimport'd class", decl);
146
 
147
  return false;
148
}
149
 
150
/* Handle the -mno-fun-dllimport target switch.  */
151
 
152
bool
153
i386_pe_valid_dllimport_attribute_p (const_tree decl)
154
{
155
   if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
156
     return false;
157
   return true;
158
}
159
 
160
/* Return string which is the function name, identified by ID, modified
161
   with a suffix consisting of an atsign (@) followed by the number of
162
   bytes of arguments.  If ID is NULL use the DECL_NAME as base. If
163
   FASTCALL is true, also add the FASTCALL_PREFIX.
164
   Return NULL if no change required.  */
165
 
166
static tree
167
gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall)
168
{
169
  HOST_WIDE_INT total = 0;
170
  const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl));
171
  char *new_str, *p;
172
  tree type = TREE_TYPE (decl);
173
  tree arg;
174
  function_args_iterator args_iter;
175
 
176
  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
177
 
178
  if (prototype_p (type))
179
    {
180
      /* This attribute is ignored for variadic functions.  */
181
      if (stdarg_p (type))
182
        return NULL_TREE;
183
 
184
      /* Quit if we hit an incomplete type.  Error is reported
185
         by convert_arguments in c-typeck.c or cp/typeck.c.  */
186
      FOREACH_FUNCTION_ARGS(type, arg, args_iter)
187
        {
188
          HOST_WIDE_INT parm_size;
189
          HOST_WIDE_INT parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
190
 
191
          if (! COMPLETE_TYPE_P (arg))
192
            break;
193
 
194
          parm_size = int_size_in_bytes (arg);
195
          if (parm_size < 0)
196
            break;
197
 
198
          /* Must round up to include padding.  This is done the same
199
             way as in store_one_arg.  */
200
          parm_size = ((parm_size + parm_boundary_bytes - 1)
201
                       / parm_boundary_bytes * parm_boundary_bytes);
202
          total += parm_size;
203
        }
204
      }
205
  /* Assume max of 8 base 10 digits in the suffix.  */
206
  p = new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 8 + 1);
207
  if (fastcall)
208
    *p++ = FASTCALL_PREFIX;
209
  sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, old_str, total);
210
 
211
  return get_identifier (new_str);
212
}
213
 
214
/* Maybe decorate and get a new identifier for the DECL of a stdcall or
215
   fastcall function. The original identifier is supplied in ID. */
216
 
217
static tree
218
i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree id)
219
{
220
  tree new_id = NULL_TREE;
221
 
222
  if (TREE_CODE (decl) == FUNCTION_DECL)
223
    {
224
      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
225
      if (lookup_attribute ("stdcall", type_attributes))
226
        new_id = gen_stdcall_or_fastcall_suffix (decl, id, false);
227
      else if (lookup_attribute ("fastcall", type_attributes))
228
        new_id = gen_stdcall_or_fastcall_suffix (decl, id, true);
229
    }
230
 
231
  return new_id;
232
}
233
 
234
/* This is used as a target hook to modify the DECL_ASSEMBLER_NAME
235
   in the language-independent default hook
236
   langhooks,c:lhd_set_decl_assembler_name ()
237
   and in cp/mangle,c:mangle_decl ().  */
238
tree
239
i386_pe_mangle_decl_assembler_name (tree decl, tree id)
240
{
241
  tree new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, id);
242
 
243
  return (new_id ? new_id : id);
244
}
245
 
246
void
247
i386_pe_encode_section_info (tree decl, rtx rtl, int first)
248
{
249
  rtx symbol;
250
  int flags;
251
 
252
  /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above.  */
253
  default_encode_section_info (decl, rtl, first);
254
 
255
  /* Careful not to prod global register variables.  */
256
  if (!MEM_P (rtl))
257
    return;
258
 
259
  symbol = XEXP (rtl, 0);
260
  gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
261
 
262
  switch (TREE_CODE (decl))
263
    {
264
    case FUNCTION_DECL:
265
      /* FIXME:  Imported stdcall names are not modified by the Ada frontend.
266
         Check and decorate the RTL name now.  */
267
      if  (strcmp (lang_hooks.name, "GNU Ada") == 0)
268
        {
269
          tree new_id;
270
          tree old_id = DECL_ASSEMBLER_NAME (decl);
271
          const char* asm_str = IDENTIFIER_POINTER (old_id);
272
          /* Do not change the identifier if a verbatim asmspec
273
             or if stdcall suffix already added. */
274
          if (!(*asm_str == '*' || strchr (asm_str, '@'))
275
              && (new_id = i386_pe_maybe_mangle_decl_assembler_name (decl,
276
                                                                     old_id)))
277
            XSTR (symbol, 0) = IDENTIFIER_POINTER (new_id);
278
        }
279
      break;
280
 
281
    case VAR_DECL:
282
      if (lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
283
        {
284
          if (DECL_INITIAL (decl)
285
              /* If an object is initialized with a ctor, the static
286
                 initialization and destruction code for it is present in
287
                 each unit defining the object.  The code that calls the
288
                 ctor is protected by a link-once guard variable, so that
289
                 the object still has link-once semantics,  */
290
              || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
291
            make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
292
          else
293
            error ("%q+D:'selectany' attribute applies only to "
294
                   "initialized objects", decl);
295
        }
296
      break;
297
 
298
    default:
299
      return;
300
    }
301
 
302
  /* Mark the decl so we can tell from the rtl whether the object is
303
     dllexport'd or dllimport'd.  tree.c: merge_dllimport_decl_attributes
304
     handles dllexport/dllimport override semantics.  */
305
  flags = (SYMBOL_REF_FLAGS (symbol) &
306
           ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT));
307
  if (i386_pe_determine_dllexport_p (decl))
308
    flags |= SYMBOL_FLAG_DLLEXPORT;
309
  else if (i386_pe_determine_dllimport_p (decl))
310
    flags |= SYMBOL_FLAG_DLLIMPORT;
311
 
312
  SYMBOL_REF_FLAGS (symbol) = flags;
313
}
314
 
315
bool
316
i386_pe_binds_local_p (const_tree exp)
317
{
318
  /* PE does not do dynamic binding.  Indeed, the only kind of
319
     non-local reference comes from a dllimport'd symbol.  */
320
  if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
321
      && DECL_DLLIMPORT_P (exp))
322
    return false;
323
 
324
  /* Or a weak one, now that they are supported.  */
325
  if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
326
      && DECL_WEAK (exp))
327
    /* But x64 gets confused and attempts to use unsupported GOTPCREL
328
       relocations if we tell it the truth, so we still return true in
329
       that case until the deeper problem can be fixed.  */
330
    return (TARGET_64BIT && DEFAULT_ABI == MS_ABI);
331
 
332
  return true;
333
}
334
 
335
/* Also strip the fastcall prefix and stdcall suffix.  */
336
 
337
const char *
338
i386_pe_strip_name_encoding_full (const char *str)
339
{
340
  const char *p;
341
  const char *name = default_strip_name_encoding (str);
342
 
343
  /* Strip leading '@' on fastcall symbols.  */
344
  if (*name == '@')
345
    name++;
346
 
347
  /* Strip trailing "@n".  */
348
  p = strchr (name, '@');
349
  if (p)
350
    return ggc_alloc_string (name, p - name);
351
 
352
  return name;
353
}
354
 
355
void
356
i386_pe_unique_section (tree decl, int reloc)
357
{
358
  int len;
359
  const char *name, *prefix;
360
  char *string;
361
 
362
  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
363
  name = i386_pe_strip_name_encoding_full (name);
364
 
365
  /* The object is put in, for example, section .text$foo.
366
     The linker will then ultimately place them in .text
367
     (everything from the $ on is stripped). Don't put
368
     read-only data in .rdata section to avoid a PE linker
369
     bug when .rdata$* grouped sections are used in code
370
     without a .rdata section.  */
371
  if (TREE_CODE (decl) == FUNCTION_DECL)
372
    prefix = ".text$";
373
  else if (decl_readonly_section (decl, reloc))
374
    prefix = ".rdata$";
375
  else
376
    prefix = ".data$";
377
  len = strlen (name) + strlen (prefix);
378
  string = XALLOCAVEC (char, len + 1);
379
  sprintf (string, "%s%s", prefix, name);
380
 
381
  DECL_SECTION_NAME (decl) = build_string (len, string);
382
}
383
 
384
/* Select a set of attributes for section NAME based on the properties
385
   of DECL and whether or not RELOC indicates that DECL's initializer
386
   might contain runtime relocations.
387
 
388
   We make the section read-only and executable for a function decl,
389
   read-only for a const data decl, and writable for a non-const data decl.
390
 
391
   If the section has already been defined, to not allow it to have
392
   different attributes, as (1) this is ambiguous since we're not seeing
393
   all the declarations up front and (2) some assemblers (e.g. SVR4)
394
   do not recognize section redefinitions.  */
395
/* ??? This differs from the "standard" PE implementation in that we
396
   handle the SHARED variable attribute.  Should this be done for all
397
   PE targets?  */
398
 
399
#define SECTION_PE_SHARED       SECTION_MACH_DEP
400
 
401
unsigned int
402
i386_pe_section_type_flags (tree decl, const char *name, int reloc)
403
{
404
  static htab_t htab;
405
  unsigned int flags;
406
  unsigned int **slot;
407
 
408
  /* The names we put in the hashtable will always be the unique
409
     versions given to us by the stringtable, so we can just use
410
     their addresses as the keys.  */
411
  if (!htab)
412
    htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
413
 
414
  if (decl && TREE_CODE (decl) == FUNCTION_DECL)
415
    flags = SECTION_CODE;
416
  else if (decl && decl_readonly_section (decl, reloc))
417
    flags = 0;
418
  else if (current_function_decl
419
           && cfun
420
           && crtl->subsections.unlikely_text_section_name
421
           && strcmp (name, crtl->subsections.unlikely_text_section_name) == 0)
422
    flags = SECTION_CODE;
423
  else if (!decl
424
           && (!current_function_decl || !cfun)
425
           && strcmp (name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0)
426
    flags = SECTION_CODE;
427
  else
428
    {
429
      flags = SECTION_WRITE;
430
 
431
      if (decl && TREE_CODE (decl) == VAR_DECL
432
          && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
433
        flags |= SECTION_PE_SHARED;
434
    }
435
 
436
  if (decl && DECL_ONE_ONLY (decl))
437
    flags |= SECTION_LINKONCE;
438
 
439
  /* See if we already have an entry for this section.  */
440
  slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
441
  if (!*slot)
442
    {
443
      *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
444
      **slot = flags;
445
    }
446
  else
447
    {
448
      if (decl && **slot != flags)
449
        error ("%q+D causes a section type conflict", decl);
450
    }
451
 
452
  return flags;
453
}
454
 
455
void
456
i386_pe_asm_named_section (const char *name, unsigned int flags,
457
                           tree decl)
458
{
459
  char flagchars[8], *f = flagchars;
460
 
461
  if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
462
    /* readonly data */
463
    {
464
      *f++ ='d';  /* This is necessary for older versions of gas.  */
465
      *f++ ='r';
466
    }
467
  else
468
    {
469
      if (flags & SECTION_CODE)
470
        *f++ = 'x';
471
      if (flags & SECTION_WRITE)
472
        *f++ = 'w';
473
      if (flags & SECTION_PE_SHARED)
474
        *f++ = 's';
475
    }
476
 
477
  /* LTO sections need 1-byte alignment to avoid confusing the
478
     zlib decompression algorithm with trailing zero pad bytes.  */
479
  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
480
                        strlen (LTO_SECTION_NAME_PREFIX)) == 0)
481
    *f++ = '0';
482
 
483
  *f = '\0';
484
 
485
  fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
486
 
487
  if (flags & SECTION_LINKONCE)
488
    {
489
      /* Functions may have been compiled at various levels of
490
         optimization so we can't use `same_size' here.
491
         Instead, have the linker pick one, without warning.
492
         If 'selectany' attribute has been specified,  MS compiler
493
         sets 'discard' characteristic, rather than telling linker
494
         to warn of size or content mismatch, so do the same.  */
495
      bool discard = (flags & SECTION_CODE)
496
                      || lookup_attribute ("selectany",
497
                                           DECL_ATTRIBUTES (decl));
498
      fprintf (asm_out_file, "\t.linkonce %s\n",
499
               (discard  ? "discard" : "same_size"));
500
    }
501
}
502
 
503
/* Beware, DECL may be NULL if compile_file() is emitting the LTO marker.  */
504
 
505
void
506
i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl,
507
                                        const char *name, HOST_WIDE_INT size,
508
                                        HOST_WIDE_INT align ATTRIBUTE_UNUSED)
509
{
510
  HOST_WIDE_INT rounded;
511
 
512
  /* Compute as in assemble_noswitch_variable, since we don't have
513
     support for aligned common on older binutils.  We must also
514
     avoid emitting a common symbol of size zero, as this is the
515
     overloaded representation that indicates an undefined external
516
     symbol in the PE object file format.  */
517
  rounded = size ? size : 1;
518
  rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
519
  rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
520
             * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
521
 
522
  i386_pe_maybe_record_exported_symbol (decl, name, 1);
523
 
524
  fprintf (stream, "\t.comm\t");
525
  assemble_name (stream, name);
526
  if (use_pe_aligned_common)
527
    fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n",
528
           size ? size : (HOST_WIDE_INT) 1,
529
           exact_log2 (align) - exact_log2 (CHAR_BIT));
530
  else
531
    fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
532
           " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size);
533
}
534
 
535
/* The Microsoft linker requires that every function be marked as
536
   DT_FCN.  When using gas on cygwin, we must emit appropriate .type
537
   directives.  */
538
 
539
#include "gsyms.h"
540
 
541
/* Mark a function appropriately.  This should only be called for
542
   functions for which we are not emitting COFF debugging information.
543
   FILE is the assembler output file, NAME is the name of the
544
   function, and PUB is nonzero if the function is globally
545
   visible.  */
546
 
547
void
548
i386_pe_declare_function_type (FILE *file, const char *name, int pub)
549
{
550
  fprintf (file, "\t.def\t");
551
  assemble_name (file, name);
552
  fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
553
           pub ? (int) C_EXT : (int) C_STAT,
554
           (int) DT_FCN << N_BTSHFT);
555
}
556
 
557
/* Keep a list of external functions.  */
558
 
559
struct GTY(()) extern_list
560
{
561
  struct extern_list *next;
562
  tree decl;
563
  const char *name;
564
};
565
 
566
static GTY(()) struct extern_list *extern_head;
567
 
568
/* Assemble an external function reference.  We need to keep a list of
569
   these, so that we can output the function types at the end of the
570
   assembly.  We can't output the types now, because we might see a
571
   definition of the function later on and emit debugging information
572
   for it then.  */
573
 
574
void
575
i386_pe_record_external_function (tree decl, const char *name)
576
{
577
  struct extern_list *p;
578
 
579
  p = (struct extern_list *) ggc_alloc (sizeof *p);
580
  p->next = extern_head;
581
  p->decl = decl;
582
  p->name = name;
583
  extern_head = p;
584
}
585
 
586
/* Keep a list of exported symbols.  */
587
 
588
struct GTY(()) export_list
589
{
590
  struct export_list *next;
591
  const char *name;
592
  int is_data;          /* used to type tag exported symbols.  */
593
};
594
 
595
static GTY(()) struct export_list *export_head;
596
 
597
/* Assemble an export symbol entry.  We need to keep a list of
598
   these, so that we can output the export list at the end of the
599
   assembly.  We used to output these export symbols in each function,
600
   but that causes problems with GNU ld when the sections are
601
   linkonce.  Beware, DECL may be NULL if compile_file() is emitting
602
   the LTO marker.  */
603
 
604
void
605
i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
606
{
607
  rtx symbol;
608
  struct export_list *p;
609
 
610
  if (!decl)
611
    return;
612
 
613
  symbol = XEXP (DECL_RTL (decl), 0);
614
  gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
615
  if (!SYMBOL_REF_DLLEXPORT_P (symbol))
616
    return;
617
 
618
  gcc_assert (TREE_PUBLIC (decl));
619
 
620
  p = (struct export_list *) ggc_alloc (sizeof *p);
621
  p->next = export_head;
622
  p->name = name;
623
  p->is_data = is_data;
624
  export_head = p;
625
}
626
 
627
#ifdef CXX_WRAP_SPEC_LIST
628
 
629
/*  Hash table equality helper function.  */
630
 
631
static int
632
wrapper_strcmp (const void *x, const void *y)
633
{
634
  return !strcmp ((const char *) x, (const char *) y);
635
}
636
 
637
/* Search for a function named TARGET in the list of library wrappers
638
   we are using, returning a pointer to it if found or NULL if not.
639
   This function might be called on quite a few symbols, and we only
640
   have the list of names of wrapped functions available to us as a
641
   spec string, so first time round we lazily initialise a hash table
642
   to make things quicker.  */
643
 
644
static const char *
645
i386_find_on_wrapper_list (const char *target)
646
{
647
  static char first_time = 1;
648
  static htab_t wrappers;
649
 
650
  if (first_time)
651
    {
652
      /* Beware that this is not a complicated parser, it assumes
653
         that any sequence of non-whitespace beginning with an
654
         underscore is one of the wrapped symbols.  For now that's
655
         adequate to distinguish symbols from spec substitutions
656
         and command-line options.  */
657
      static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST;
658
      char *bufptr;
659
      /* Breaks up the char array into separated strings
660
         strings and enter them into the hash table.  */
661
      wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
662
        0, xcalloc, free);
663
      for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
664
        {
665
          char *found = NULL;
666
          if (ISSPACE (*bufptr))
667
            continue;
668
          if (*bufptr == '_')
669
            found = bufptr;
670
          while (*bufptr && !ISSPACE (*bufptr))
671
            ++bufptr;
672
          if (*bufptr)
673
            *bufptr = 0;
674
          if (found)
675
            *htab_find_slot (wrappers, found, INSERT) = found;
676
        }
677
      first_time = 0;
678
    }
679
 
680
  return (const char *) htab_find (wrappers, target);
681
}
682
 
683
#endif /* CXX_WRAP_SPEC_LIST */
684
 
685
/* This is called at the end of assembly.  For each external function
686
   which has not been defined, we output a declaration now.  We also
687
   output the .drectve section.  */
688
 
689
void
690
i386_pe_file_end (void)
691
{
692
  struct extern_list *p;
693
 
694
  for (p = extern_head; p != NULL; p = p->next)
695
    {
696
      tree decl;
697
 
698
      decl = p->decl;
699
 
700
      /* Positively ensure only one declaration for any given symbol.  */
701
      if (! TREE_ASM_WRITTEN (decl)
702
          && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
703
        {
704
#ifdef CXX_WRAP_SPEC_LIST
705
          /* To ensure the DLL that provides the corresponding real
706
             functions is still loaded at runtime, we must reference
707
             the real function so that an (unused) import is created.  */
708
          const char *realsym = i386_find_on_wrapper_list (p->name);
709
          if (realsym)
710
            i386_pe_declare_function_type (asm_out_file,
711
                concat ("__real_", realsym, NULL), TREE_PUBLIC (decl));
712
#endif /* CXX_WRAP_SPEC_LIST */
713
          TREE_ASM_WRITTEN (decl) = 1;
714
          i386_pe_declare_function_type (asm_out_file, p->name,
715
                                         TREE_PUBLIC (decl));
716
        }
717
    }
718
 
719
  if (export_head)
720
    {
721
      struct export_list *q;
722
      drectve_section ();
723
      for (q = export_head; q != NULL; q = q->next)
724
        {
725
          fprintf (asm_out_file, "\t.ascii \" -export:\\\"%s\\\"%s\"\n",
726
                   default_strip_name_encoding (q->name),
727
                   (q->is_data ? ",data" : ""));
728
        }
729
    }
730
}
731
 
732
#include "gt-winnt.h"

powered by: WebSVN 2.1.0

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