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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [i386/] [winnt.c] - Blame information for rev 38

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

Line No. Rev Author Line
1 38 julius
/* 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  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 "ggc.h"
36
 
37
/* i386/PE specific attribute support.
38
 
39
   i386/PE has two new attributes:
40
   dllexport - for exporting a function/variable that will live in a dll
41
   dllimport - for importing a function/variable from a dll
42
 
43
   Microsoft allows multiple declspecs in one __declspec, separating
44
   them with spaces.  We do NOT support this.  Instead, use __declspec
45
   multiple times.
46
*/
47
 
48
static tree associated_type (tree);
49
static tree gen_stdcall_or_fastcall_suffix (tree, bool);
50
static bool i386_pe_dllexport_p (tree);
51
static bool i386_pe_dllimport_p (tree);
52
static void i386_pe_mark_dllexport (tree);
53
static void i386_pe_mark_dllimport (tree);
54
 
55
/* This is we how mark internal identifiers with dllimport or dllexport
56
   attributes.  */
57
#ifndef DLL_IMPORT_PREFIX
58
#define DLL_IMPORT_PREFIX "#i."
59
#endif
60
#ifndef DLL_EXPORT_PREFIX
61
#define DLL_EXPORT_PREFIX "#e."
62
#endif
63
 
64
/* Handle a "shared" attribute;
65
   arguments as in struct attribute_spec.handler.  */
66
tree
67
ix86_handle_shared_attribute (tree *node, tree name,
68
                              tree args ATTRIBUTE_UNUSED,
69
                              int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
70
{
71
  if (TREE_CODE (*node) != VAR_DECL)
72
    {
73
      warning (OPT_Wattributes, "%qs attribute only applies to variables",
74
               IDENTIFIER_POINTER (name));
75
      *no_add_attrs = true;
76
    }
77
 
78
  return NULL_TREE;
79
}
80
 
81
/* Handle a "selectany" attribute;
82
   arguments as in struct attribute_spec.handler.  */
83
tree
84
ix86_handle_selectany_attribute (tree *node, tree name,
85
                                 tree args ATTRIBUTE_UNUSED,
86
                                 int flags ATTRIBUTE_UNUSED,
87
                                 bool *no_add_attrs)
88
{
89
  /* The attribute applies only to objects that are initialized and have
90
     external linkage.  However, we may not know about initialization
91
     until the language frontend has processed the decl. We'll check for
92
     initialization later in encode_section_info.  */
93
  if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node))
94
    {
95
      error ("%qs attribute applies only to initialized variables"
96
             " with external linkage",  IDENTIFIER_POINTER (name));
97
      *no_add_attrs = true;
98
    }
99
 
100
  return NULL_TREE;
101
}
102
 
103
 
104
/* Return the type that we should use to determine if DECL is
105
   imported or exported.  */
106
 
107
static tree
108
associated_type (tree decl)
109
{
110
  return  (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
111
            ?  DECL_CONTEXT (decl) : NULL_TREE;
112
}
113
 
114
 
115
/* Return true if DECL is a dllexport'd object.  */
116
 
117
static bool
118
i386_pe_dllexport_p (tree decl)
119
{
120
  if (TREE_CODE (decl) != VAR_DECL
121
       && TREE_CODE (decl) != FUNCTION_DECL)
122
    return false;
123
 
124
  if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
125
    return true;
126
 
127
  /* Also mark class members of exported classes with dllexport.  */
128
  if (associated_type (decl)
129
      && lookup_attribute ("dllexport",
130
                            TYPE_ATTRIBUTES (associated_type (decl))))
131
    return i386_pe_type_dllexport_p (decl);
132
 
133
  return false;
134
}
135
 
136
static bool
137
i386_pe_dllimport_p (tree decl)
138
{
139
  if (TREE_CODE (decl) != VAR_DECL
140
       && TREE_CODE (decl) != FUNCTION_DECL)
141
    return false;
142
 
143
  /* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P flag.
144
     We may need to override an earlier decision.  */
145
  if (DECL_DLLIMPORT_P (decl)
146
      && lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)))
147
    {
148
       /* Make a final check to see if this is a definition before we generate
149
          RTL for an indirect reference.  */
150
       if (!DECL_EXTERNAL (decl))
151
        {
152
          error ("%q+D: definition is marked as dllimport", decl);
153
          DECL_DLLIMPORT_P (decl) = 0;
154
          return false;
155
        }
156
      return true;
157
    }
158
  /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
159
     by  targetm.cxx.adjust_class_at_definition.  Check again to emit
160
     warnings if the class attribute has been overridden by an
161
     out-of-class definition.  */
162
  else if (associated_type (decl)
163
           && lookup_attribute ("dllimport",
164
                                TYPE_ATTRIBUTES (associated_type (decl))))
165
    return i386_pe_type_dllimport_p (decl);
166
 
167
  return false;
168
}
169
 
170
/* Handle the -mno-fun-dllimport target switch.  */
171
bool
172
i386_pe_valid_dllimport_attribute_p (tree decl)
173
{
174
   if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
175
     return false;
176
   return true;
177
}
178
 
179
/* Return nonzero if SYMBOL is marked as being dllexport'd.  */
180
 
181
int
182
i386_pe_dllexport_name_p (const char *symbol)
183
{
184
  return (strncmp (DLL_EXPORT_PREFIX, symbol,
185
                   strlen (DLL_EXPORT_PREFIX)) == 0);
186
}
187
 
188
/* Return nonzero if SYMBOL is marked as being dllimport'd.  */
189
 
190
int
191
i386_pe_dllimport_name_p (const char *symbol)
192
{
193
  return (strncmp (DLL_IMPORT_PREFIX, symbol,
194
                   strlen (DLL_IMPORT_PREFIX)) == 0);
195
}
196
 
197
/* Mark a DECL as being dllexport'd.
198
   Note that we override the previous setting (e.g.: dllimport).  */
199
 
200
static void
201
i386_pe_mark_dllexport (tree decl)
202
{
203
  const char *oldname;
204
  char  *newname;
205
  rtx rtlname;
206
  rtx symref;
207
  tree idp;
208
 
209
  rtlname = XEXP (DECL_RTL (decl), 0);
210
  if (GET_CODE (rtlname) == MEM)
211
    rtlname = XEXP (rtlname, 0);
212
  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
213
  oldname = XSTR (rtlname, 0);
214
  if (i386_pe_dllimport_name_p (oldname))
215
    {
216
      warning (0, "inconsistent dll linkage for %q+D, dllexport assumed",
217
               decl);
218
     /* Remove DLL_IMPORT_PREFIX.  */
219
      oldname += strlen (DLL_IMPORT_PREFIX);
220
    }
221
  else if (i386_pe_dllexport_name_p (oldname))
222
    return;  /*  already done  */
223
 
224
  newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
225
  sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
226
 
227
  /* We pass newname through get_identifier to ensure it has a unique
228
     address.  RTL processing can sometimes peek inside the symbol ref
229
     and compare the string's addresses to see if two symbols are
230
     identical.  */
231
  idp = get_identifier (newname);
232
 
233
  symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
234
  SET_SYMBOL_REF_DECL (symref, decl);
235
  XEXP (DECL_RTL (decl), 0) = symref;
236
}
237
 
238
/* Mark a DECL as being dllimport'd.  */
239
 
240
static void
241
i386_pe_mark_dllimport (tree decl)
242
{
243
  const char *oldname;
244
  char  *newname;
245
  tree idp;
246
  rtx rtlname, newrtl;
247
  rtx symref;
248
 
249
  rtlname = XEXP (DECL_RTL (decl), 0);
250
  if (GET_CODE (rtlname) == MEM)
251
    rtlname = XEXP (rtlname, 0);
252
  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
253
  oldname = XSTR (rtlname, 0);
254
  if (i386_pe_dllexport_name_p (oldname))
255
    {
256
      error ("%qs declared as both exported to and imported from a DLL",
257
             IDENTIFIER_POINTER (DECL_NAME (decl)));
258
      return;
259
    }
260
  else if (i386_pe_dllimport_name_p (oldname))
261
    {
262
      /* Already done, but do a sanity check to prevent assembler
263
         errors.  */
264
      gcc_assert (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
265
                  && DECL_DLLIMPORT_P (decl));
266
      return;
267
    }
268
 
269
  newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
270
  sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
271
 
272
  /* We pass newname through get_identifier to ensure it has a unique
273
     address.  RTL processing can sometimes peek inside the symbol ref
274
     and compare the string's addresses to see if two symbols are
275
     identical.  */
276
  idp = get_identifier (newname);
277
 
278
  symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
279
  SET_SYMBOL_REF_DECL (symref, decl);
280
  newrtl = gen_rtx_MEM (Pmode,symref);
281
  XEXP (DECL_RTL (decl), 0) = newrtl;
282
 
283
  DECL_DLLIMPORT_P (decl) = 1;
284
}
285
 
286
/* Return string which is the former assembler name modified with a
287
   suffix consisting of an atsign (@) followed by the number of bytes of
288
   arguments.  If FASTCALL is true, also add the FASTCALL_PREFIX.  */
289
 
290
static tree
291
gen_stdcall_or_fastcall_suffix (tree decl, bool fastcall)
292
{
293
  int total = 0;
294
  /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
295
     of DECL_ASSEMBLER_NAME.  */
296
   const char *asmname =  IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
297
  char *newsym;
298
  char *p;
299
  tree formal_type;
300
 
301
  /* Do not change the identifier if a verbatim asmspec or already done. */
302
  if (*asmname == '*' || strchr (asmname, '@'))
303
    return DECL_ASSEMBLER_NAME (decl);
304
 
305
  formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
306
  if (formal_type != NULL_TREE)
307
    {
308
      /* These attributes are ignored for variadic functions in
309
         i386.c:ix86_return_pops_args. For compatibility with MS
310
         compiler do not add @0 suffix here.  */
311
      if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
312
        return DECL_ASSEMBLER_NAME (decl);
313
 
314
      /* Quit if we hit an incomplete type.  Error is reported
315
         by convert_arguments in c-typeck.c or cp/typeck.c.  */
316
      while (TREE_VALUE (formal_type) != void_type_node
317
             && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
318
        {
319
          int parm_size
320
            = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
321
            /* Must round up to include padding.  This is done the same
322
               way as in store_one_arg.  */
323
          parm_size = ((parm_size + PARM_BOUNDARY - 1)
324
                       / PARM_BOUNDARY * PARM_BOUNDARY);
325
          total += parm_size;
326
          formal_type = TREE_CHAIN (formal_type);\
327
        }
328
     }
329
 
330
  /* Assume max of 8 base 10 digits in the suffix.  */
331
  newsym = alloca (1 + strlen (asmname) + 1 + 8 + 1);
332
  p = newsym;
333
  if (fastcall)
334
    *p++ = FASTCALL_PREFIX;
335
  sprintf (p, "%s@%d", asmname, total/BITS_PER_UNIT);
336
  return get_identifier (newsym);
337
}
338
 
339
void
340
i386_pe_encode_section_info (tree decl, rtx rtl, int first)
341
{
342
  default_encode_section_info (decl, rtl, first);
343
 
344
  if (first && TREE_CODE (decl) == FUNCTION_DECL)
345
    {
346
      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
347
      tree newid = NULL_TREE;
348
 
349
      if (lookup_attribute ("stdcall", type_attributes))
350
        newid = gen_stdcall_or_fastcall_suffix (decl, false);
351
      else if (lookup_attribute ("fastcall", type_attributes))
352
        newid = gen_stdcall_or_fastcall_suffix (decl, true);
353
      if (newid != NULL_TREE)
354
        {
355
          rtx rtlname = XEXP (rtl, 0);
356
          if (GET_CODE (rtlname) == MEM)
357
            rtlname = XEXP (rtlname, 0);
358
          XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
359
          /* These attributes must be present on first declaration,
360
             change_decl_assembler_name will warn if they are added
361
             later and the decl has been referenced, but duplicate_decls
362
             should catch the mismatch before this is called.  */
363
          change_decl_assembler_name (decl, newid);
364
        }
365
    }
366
 
367
  else if (TREE_CODE (decl) == VAR_DECL
368
           && lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
369
    {
370
      if (DECL_INITIAL (decl)
371
          /* If an object is initialized with a ctor, the static
372
             initialization and destruction code for it is present in
373
             each unit defining the object.  The code that calls the
374
             ctor is protected by a link-once guard variable, so that
375
             the object still has link-once semantics,  */
376
           || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
377
        make_decl_one_only (decl);
378
      else
379
        error ("%q+D:'selectany' attribute applies only to initialized objects",
380
               decl);
381
    }
382
 
383
  /* Mark the decl so we can tell from the rtl whether the object is
384
     dllexport'd or dllimport'd.  tree.c: merge_dllimport_decl_attributes
385
     handles dllexport/dllimport override semantics.  */
386
 
387
  if (i386_pe_dllexport_p (decl))
388
    i386_pe_mark_dllexport (decl);
389
  else if (i386_pe_dllimport_p (decl))
390
    i386_pe_mark_dllimport (decl);
391
  /* It might be that DECL has been declared as dllimport, but a
392
     subsequent definition nullified that.  Assert that
393
     tree.c: merge_dllimport_decl_attributes has removed the attribute
394
     before the RTL name was marked with the DLL_IMPORT_PREFIX.  */
395
  else
396
    gcc_assert (!((TREE_CODE (decl) == FUNCTION_DECL
397
                   || TREE_CODE (decl) == VAR_DECL)
398
                  && rtl != NULL_RTX
399
                  && GET_CODE (rtl) == MEM
400
                  && GET_CODE (XEXP (rtl, 0)) == MEM
401
                  && GET_CODE (XEXP (XEXP (rtl, 0), 0)) == SYMBOL_REF
402
                  && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (rtl, 0), 0), 0))));
403
}
404
 
405
/* Strip only the leading encoding, leaving the stdcall suffix and fastcall
406
   prefix if it exists.  */
407
 
408
const char *
409
i386_pe_strip_name_encoding (const char *str)
410
{
411
  if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
412
      == 0)
413
    str += strlen (DLL_IMPORT_PREFIX);
414
  else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
415
           == 0)
416
    str += strlen (DLL_EXPORT_PREFIX);
417
  if (*str == '*')
418
    str += 1;
419
  return str;
420
}
421
 
422
/* Also strip the fastcall prefix and stdcall suffix.  */
423
 
424
const char *
425
i386_pe_strip_name_encoding_full (const char *str)
426
{
427
  const char *p;
428
  const char *name = i386_pe_strip_name_encoding (str);
429
 
430
  /* Strip leading '@' on fastcall symbols.  */
431
  if (*name == '@')
432
    name++;
433
 
434
  /* Strip trailing "@n".  */
435
  p = strchr (name, '@');
436
  if (p)
437
    return ggc_alloc_string (name, p - name);
438
 
439
  return name;
440
}
441
 
442
/* Output a reference to a label. Fastcall symbols are prefixed with @,
443
   whereas symbols for functions using other calling conventions don't
444
   have a prefix (unless they are marked dllimport or dllexport).  */
445
 
446
void i386_pe_output_labelref (FILE *stream, const char *name)
447
{
448
  if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
449
      == 0)
450
    /* A dll import */
451
    {
452
      if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
453
      /* A dllimport fastcall symbol.  */
454
        {
455
          fprintf (stream, "__imp_%s",
456
                   i386_pe_strip_name_encoding (name));
457
        }
458
      else
459
      /* A dllimport non-fastcall symbol.  */
460
        {
461
          fprintf (stream, "__imp__%s",
462
                   i386_pe_strip_name_encoding (name));
463
        }
464
    }
465
  else if ((name[0] == FASTCALL_PREFIX)
466
           || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
467
               == 0
468
               && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX))
469
    /* A fastcall symbol.  */
470
    {
471
      fprintf (stream, "%s",
472
               i386_pe_strip_name_encoding (name));
473
    }
474
  else
475
    /* Everything else.  */
476
    {
477
      fprintf (stream, "%s%s", USER_LABEL_PREFIX,
478
               i386_pe_strip_name_encoding (name));
479
    }
480
}
481
 
482
void
483
i386_pe_unique_section (tree decl, int reloc)
484
{
485
  int len;
486
  const char *name, *prefix;
487
  char *string;
488
 
489
  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
490
  name = i386_pe_strip_name_encoding_full (name);
491
 
492
  /* The object is put in, for example, section .text$foo.
493
     The linker will then ultimately place them in .text
494
     (everything from the $ on is stripped). Don't put
495
     read-only data in .rdata section to avoid a PE linker
496
     bug when .rdata$* grouped sections are used in code
497
     without a .rdata section.  */
498
  if (TREE_CODE (decl) == FUNCTION_DECL)
499
    prefix = ".text$";
500
  else if (decl_readonly_section (decl, reloc))
501
    prefix = ".rdata$";
502
  else
503
    prefix = ".data$";
504
  len = strlen (name) + strlen (prefix);
505
  string = alloca (len + 1);
506
  sprintf (string, "%s%s", prefix, name);
507
 
508
  DECL_SECTION_NAME (decl) = build_string (len, string);
509
}
510
 
511
/* Select a set of attributes for section NAME based on the properties
512
   of DECL and whether or not RELOC indicates that DECL's initializer
513
   might contain runtime relocations.
514
 
515
   We make the section read-only and executable for a function decl,
516
   read-only for a const data decl, and writable for a non-const data decl.
517
 
518
   If the section has already been defined, to not allow it to have
519
   different attributes, as (1) this is ambiguous since we're not seeing
520
   all the declarations up front and (2) some assemblers (e.g. SVR4)
521
   do not recognize section redefinitions.  */
522
/* ??? This differs from the "standard" PE implementation in that we
523
   handle the SHARED variable attribute.  Should this be done for all
524
   PE targets?  */
525
 
526
#define SECTION_PE_SHARED       SECTION_MACH_DEP
527
 
528
unsigned int
529
i386_pe_section_type_flags (tree decl, const char *name, int reloc)
530
{
531
  static htab_t htab;
532
  unsigned int flags;
533
  unsigned int **slot;
534
 
535
  /* The names we put in the hashtable will always be the unique
536
     versions given to us by the stringtable, so we can just use
537
     their addresses as the keys.  */
538
  if (!htab)
539
    htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
540
 
541
  if (decl && TREE_CODE (decl) == FUNCTION_DECL)
542
    flags = SECTION_CODE;
543
  else if (decl && decl_readonly_section (decl, reloc))
544
    flags = 0;
545
  else
546
    {
547
      flags = SECTION_WRITE;
548
 
549
      if (decl && TREE_CODE (decl) == VAR_DECL
550
          && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
551
        flags |= SECTION_PE_SHARED;
552
    }
553
 
554
  if (decl && DECL_ONE_ONLY (decl))
555
    flags |= SECTION_LINKONCE;
556
 
557
  /* See if we already have an entry for this section.  */
558
  slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
559
  if (!*slot)
560
    {
561
      *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
562
      **slot = flags;
563
    }
564
  else
565
    {
566
      if (decl && **slot != flags)
567
        error ("%q+D causes a section type conflict", decl);
568
    }
569
 
570
  return flags;
571
}
572
 
573
void
574
i386_pe_asm_named_section (const char *name, unsigned int flags,
575
                           tree decl)
576
{
577
  char flagchars[8], *f = flagchars;
578
 
579
  if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
580
    /* readonly data */
581
    {
582
      *f++ ='d';  /* This is necessary for older versions of gas.  */
583
      *f++ ='r';
584
    }
585
  else
586
    {
587
      if (flags & SECTION_CODE)
588
        *f++ = 'x';
589
      if (flags & SECTION_WRITE)
590
        *f++ = 'w';
591
      if (flags & SECTION_PE_SHARED)
592
        *f++ = 's';
593
    }
594
 
595
  *f = '\0';
596
 
597
  fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
598
 
599
  if (flags & SECTION_LINKONCE)
600
    {
601
      /* Functions may have been compiled at various levels of
602
         optimization so we can't use `same_size' here.
603
         Instead, have the linker pick one, without warning.
604
         If 'selectany' attribute has been specified,  MS compiler
605
         sets 'discard' characteristic, rather than telling linker
606
         to warn of size or content mismatch, so do the same.  */
607
      bool discard = (flags & SECTION_CODE)
608
                      || lookup_attribute ("selectany",
609
                                           DECL_ATTRIBUTES (decl));
610
      fprintf (asm_out_file, "\t.linkonce %s\n",
611
               (discard  ? "discard" : "same_size"));
612
    }
613
}
614
 
615
/* The Microsoft linker requires that every function be marked as
616
   DT_FCN.  When using gas on cygwin, we must emit appropriate .type
617
   directives.  */
618
 
619
#include "gsyms.h"
620
 
621
/* Mark a function appropriately.  This should only be called for
622
   functions for which we are not emitting COFF debugging information.
623
   FILE is the assembler output file, NAME is the name of the
624
   function, and PUBLIC is nonzero if the function is globally
625
   visible.  */
626
 
627
void
628
i386_pe_declare_function_type (FILE *file, const char *name, int public)
629
{
630
  fprintf (file, "\t.def\t");
631
  assemble_name (file, name);
632
  fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
633
           public ? (int) C_EXT : (int) C_STAT,
634
           (int) DT_FCN << N_BTSHFT);
635
}
636
 
637
/* Keep a list of external functions.  */
638
 
639
struct extern_list GTY(())
640
{
641
  struct extern_list *next;
642
  tree decl;
643
  const char *name;
644
};
645
 
646
static GTY(()) struct extern_list *extern_head;
647
 
648
/* Assemble an external function reference.  We need to keep a list of
649
   these, so that we can output the function types at the end of the
650
   assembly.  We can't output the types now, because we might see a
651
   definition of the function later on and emit debugging information
652
   for it then.  */
653
 
654
void
655
i386_pe_record_external_function (tree decl, const char *name)
656
{
657
  struct extern_list *p;
658
 
659
  p = (struct extern_list *) ggc_alloc (sizeof *p);
660
  p->next = extern_head;
661
  p->decl = decl;
662
  p->name = name;
663
  extern_head = p;
664
}
665
 
666
/* Keep a list of exported symbols.  */
667
 
668
struct export_list GTY(())
669
{
670
  struct export_list *next;
671
  const char *name;
672
  int is_data;          /* used to type tag exported symbols.  */
673
};
674
 
675
static GTY(()) struct export_list *export_head;
676
 
677
/* Assemble an export symbol entry.  We need to keep a list of
678
   these, so that we can output the export list at the end of the
679
   assembly.  We used to output these export symbols in each function,
680
   but that causes problems with GNU ld when the sections are
681
   linkonce.  */
682
 
683
void
684
i386_pe_record_exported_symbol (const char *name, int is_data)
685
{
686
  struct export_list *p;
687
 
688
  p = (struct export_list *) ggc_alloc (sizeof *p);
689
  p->next = export_head;
690
  p->name = name;
691
  p->is_data = is_data;
692
  export_head = p;
693
}
694
 
695
/* This is called at the end of assembly.  For each external function
696
   which has not been defined, we output a declaration now.  We also
697
   output the .drectve section.  */
698
 
699
void
700
i386_pe_file_end (void)
701
{
702
  struct extern_list *p;
703
 
704
  ix86_file_end ();
705
 
706
  for (p = extern_head; p != NULL; p = p->next)
707
    {
708
      tree decl;
709
 
710
      decl = p->decl;
711
 
712
      /* Positively ensure only one declaration for any given symbol.  */
713
      if (! TREE_ASM_WRITTEN (decl)
714
          && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
715
        {
716
          TREE_ASM_WRITTEN (decl) = 1;
717
          i386_pe_declare_function_type (asm_out_file, p->name,
718
                                         TREE_PUBLIC (decl));
719
        }
720
    }
721
 
722
  if (export_head)
723
    {
724
      struct export_list *q;
725
      drectve_section ();
726
      for (q = export_head; q != NULL; q = q->next)
727
        {
728
          fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
729
                   i386_pe_strip_name_encoding (q->name),
730
                   (q->is_data) ? ",data" : "");
731
        }
732
    }
733
}
734
 
735
#include "gt-winnt.h"

powered by: WebSVN 2.1.0

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