summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config/i386/winnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/config/i386/winnt.c')
-rw-r--r--contrib/gcc/config/i386/winnt.c379
1 files changed, 236 insertions, 143 deletions
diff --git a/contrib/gcc/config/i386/winnt.c b/contrib/gcc/config/i386/winnt.c
index 01493a2..f8621b4 100644
--- a/contrib/gcc/config/i386/winnt.c
+++ b/contrib/gcc/config/i386/winnt.c
@@ -1,6 +1,6 @@
/* Subroutines for insn-output.c for Windows NT.
Contributed by Douglas Rupp (drupp@cs.washington.edu)
- Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -44,22 +46,28 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
multiple times.
*/
-static tree associated_type PARAMS ((tree));
-const char * gen_stdcall_suffix PARAMS ((tree));
-int i386_pe_dllexport_p PARAMS ((tree));
-int i386_pe_dllimport_p PARAMS ((tree));
-void i386_pe_mark_dllexport PARAMS ((tree));
-void i386_pe_mark_dllimport PARAMS ((tree));
+static tree associated_type (tree);
+static const char * gen_stdcall_suffix (tree);
+static const char * gen_fastcall_suffix (tree);
+static int i386_pe_dllexport_p (tree);
+static int i386_pe_dllimport_p (tree);
+static void i386_pe_mark_dllexport (tree);
+static void i386_pe_mark_dllimport (tree);
+
+/* This is we how mark internal identifiers with dllimport or dllexport
+ attributes. */
+#ifndef DLL_IMPORT_PREFIX
+#define DLL_IMPORT_PREFIX "#i."
+#endif
+#ifndef DLL_EXPORT_PREFIX
+#define DLL_EXPORT_PREFIX "#e."
+#endif
/* Handle a "dllimport" or "dllexport" attribute;
arguments as in struct attribute_spec.handler. */
tree
-ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
- tree * pnode;
- tree name;
- tree args;
- int flags;
- bool *no_add_attrs;
+ix86_handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
+ bool *no_add_attrs)
{
tree node = *pnode;
@@ -93,7 +101,7 @@ ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node)
&& !DECL_INLINE (node))
{
- error_with_decl (node, "function `%s' definition is marked dllimport.");
+ error ("%Jfunction `%D' definition is marked dllimport.", node, node);
*no_add_attrs = true;
}
@@ -101,27 +109,28 @@ ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
{
if (DECL_INITIAL (node))
{
- error_with_decl (node,"variable `%s' definition is marked dllimport.");
+ error ("%Jvariable `%D' definition is marked dllimport.",
+ node, node);
*no_add_attrs = true;
}
/* `extern' needn't be specified with dllimport.
Specify `extern' now and hope for the best. Sigh. */
- DECL_EXTERNAL (node) = 1;
+ DECL_EXTERNAL (node) = 1;
/* Also, implicitly give dllimport'd variables declared within
a function global scope, unless declared static. */
if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
- TREE_PUBLIC (node) = 1;
+ TREE_PUBLIC (node) = 1;
}
}
- /* Report error if symbol is not accessible at global scope. */
+ /* Report error if symbol is not accessible at global scope. */
if (!TREE_PUBLIC (node)
&& (TREE_CODE (node) == VAR_DECL
- || TREE_CODE (node) == FUNCTION_DECL))
+ || TREE_CODE (node) == FUNCTION_DECL))
{
- error_with_decl (node, "external linkage required for symbol '%s' because of '%s' attribute.",
- IDENTIFIER_POINTER (name));
+ error ("%Jexternal linkage required for symbol '%D' because of "
+ "'%s' attribute.", node, node, IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
@@ -131,12 +140,9 @@ ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
/* Handle a "shared" attribute;
arguments as in struct attribute_spec.handler. */
tree
-ix86_handle_shared_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+ix86_handle_shared_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) != VAR_DECL)
{
@@ -152,8 +158,7 @@ ix86_handle_shared_attribute (node, name, args, flags, no_add_attrs)
imported or exported. */
static tree
-associated_type (decl)
- tree decl;
+associated_type (tree decl)
{
tree t = NULL_TREE;
@@ -161,10 +166,13 @@ associated_type (decl)
to the containing class. So we look at the 'this' arg. */
if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
{
- /* Artificial methods are not affected by the import/export status of
- their class unless they are virtual. */
- if (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl))
- t = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))));
+ /* Artificial methods are not affected by the import/export status
+ of their class unless they are COMDAT. Implicit copy ctor's and
+ dtor's are not affected by class status but virtual and
+ non-virtual thunks are. */
+ if (!DECL_ARTIFICIAL (decl) || DECL_COMDAT (decl))
+ t = TYPE_MAIN_VARIANT
+ (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
}
else if (DECL_CONTEXT (decl)
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
@@ -175,9 +183,8 @@ associated_type (decl)
/* Return nonzero if DECL is a dllexport'd object. */
-int
-i386_pe_dllexport_p (decl)
- tree decl;
+static int
+i386_pe_dllexport_p (tree decl)
{
tree exp;
@@ -202,9 +209,8 @@ i386_pe_dllexport_p (decl)
/* Return nonzero if DECL is a dllimport'd object. */
-int
-i386_pe_dllimport_p (decl)
- tree decl;
+static int
+i386_pe_dllimport_p (tree decl)
{
tree imp;
int context_imp = 0;
@@ -239,17 +245,19 @@ i386_pe_dllimport_p (decl)
{
/* Don't warn about artificial methods. */
if (!DECL_ARTIFICIAL (decl))
- warning_with_decl (decl,"function '%s' is defined after prior declaration as dllimport: attribute ignored.");
+ warning ("%Jfunction '%D' is defined after prior declaration "
+ "as dllimport: attribute ignored", decl, decl);
return 0;
}
/* We ignore the dllimport attribute for inline member functions.
- This differs from MSVC behaviour which treats it like GNUC
- 'extern inline' extension. */
+ This differs from MSVC behavior which treats it like GNUC
+ 'extern inline' extension. */
else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
{
if (extra_warnings)
- warning_with_decl (decl, "inline function '%s' is declared as dllimport: attribute ignored.");
+ warning ("%Jinline function '%D' is declared as dllimport: "
+ "attribute ignored.", decl, decl);
return 0;
}
@@ -260,16 +268,19 @@ i386_pe_dllimport_p (decl)
&& !DECL_EXTERNAL (decl) && context_imp)
{
if (!DECL_VIRTUAL_P (decl))
- error_with_decl (decl, "definition of static data member '%s' of dllimport'd class.");
- return 0;
+ error ("%Jdefinition of static data member '%D' of "
+ "dllimport'd class.", decl, decl);
+ return 0;
}
/* Since we can't treat a pointer to a dllimport'd symbol as a
constant address, we turn off the attribute on C++ virtual
- methods to allow creation of vtables using thunks. */
+ methods to allow creation of vtables using thunks. Don't mark
+ artificial methods either (in associated_type, only COMDAT
+ artificial method get import status from class context). */
else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
- && (DECL_VIRTUAL_P (decl)))
- return 0;
+ && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
+ return 0;
return 1;
}
@@ -280,29 +291,26 @@ i386_pe_dllimport_p (decl)
/* Return nonzero if SYMBOL is marked as being dllexport'd. */
int
-i386_pe_dllexport_name_p (symbol)
- const char *symbol;
+i386_pe_dllexport_name_p (const char *symbol)
{
- return symbol[0] == DLL_IMPORT_EXPORT_PREFIX
- && symbol[1] == 'e' && symbol[2] == '.';
+ return (strncmp (DLL_EXPORT_PREFIX, symbol,
+ strlen (DLL_EXPORT_PREFIX)) == 0);
}
/* Return nonzero if SYMBOL is marked as being dllimport'd. */
int
-i386_pe_dllimport_name_p (symbol)
- const char *symbol;
+i386_pe_dllimport_name_p (const char *symbol)
{
- return symbol[0] == DLL_IMPORT_EXPORT_PREFIX
- && symbol[1] == 'i' && symbol[2] == '.';
+ return (strncmp (DLL_IMPORT_PREFIX, symbol,
+ strlen (DLL_IMPORT_PREFIX)) == 0);
}
/* Mark a DECL as being dllexport'd.
Note that we override the previous setting (eg: dllimport). */
-void
-i386_pe_mark_dllexport (decl)
- tree decl;
+static void
+i386_pe_mark_dllexport (tree decl)
{
const char *oldname;
char *newname;
@@ -319,16 +327,17 @@ i386_pe_mark_dllexport (decl)
abort ();
if (i386_pe_dllimport_name_p (oldname))
{
- warning_with_decl (decl,"inconsistent dll linkage for '%s': dllexport assumed.");
+ warning ("%Jinconsistent dll linkage for '%D', dllexport assumed.",
+ decl, decl);
/* Remove DLL_IMPORT_PREFIX. */
- oldname += 9;
+ oldname += strlen (DLL_IMPORT_PREFIX);
DECL_NON_ADDR_CONST_P (decl) = 0;
}
else if (i386_pe_dllexport_name_p (oldname))
- return; /* already done */
+ return; /* already done */
- newname = alloca (strlen (oldname) + 4);
- sprintf (newname, "%ce.%s", DLL_IMPORT_EXPORT_PREFIX, oldname);
+ newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
+ sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
/* We pass newname through get_identifier to ensure it has a unique
address. RTL processing can sometimes peek inside the symbol ref
@@ -342,9 +351,8 @@ i386_pe_mark_dllexport (decl)
/* Mark a DECL as being dllimport'd. */
-void
-i386_pe_mark_dllimport (decl)
- tree decl;
+static void
+i386_pe_mark_dllimport (tree decl)
{
const char *oldname;
char *newname;
@@ -367,17 +375,18 @@ i386_pe_mark_dllimport (decl)
}
else if (i386_pe_dllimport_name_p (oldname))
{
- /* Already done, but do a sanity check to prevent assembler errors. */
+ /* Already done, but do a sanity check to prevent assembler errors. */
if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
{
- error_with_decl (decl, "failure in redeclaration of '%s': dllimport'd symbol lacks external linkage.");
+ error ("%Jfailure in redeclaration of '%D': dllimport'd "
+ "symbol lacks external linkage.", decl, decl);
abort();
}
- return;
+ return;
}
- newname = alloca (strlen (oldname) + 11);
- sprintf (newname, "%ci._imp__%s", DLL_IMPORT_EXPORT_PREFIX, oldname);
+ newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
+ sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
/* We pass newname through get_identifier to ensure it has a unique
address. RTL processing can sometimes peek inside the symbol ref
@@ -394,13 +403,51 @@ i386_pe_mark_dllimport (decl)
DECL_NON_ADDR_CONST_P (decl) = 1;
}
-/* Return string which is the former assembler name modified with a
- suffix consisting of an atsign (@) followed by the number of bytes of
+/* Return string which is the former assembler name modified with a
+ prefix consisting of FASTCALL_PREFIX and a suffix consisting of an
+ atsign (@) followed by the number of bytes of arguments. */
+
+static const char *
+gen_fastcall_suffix (tree decl)
+{
+ int total = 0;
+ const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ char *newsym;
+
+ if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
+ if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
+ == void_type_node)
+ {
+ tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
+
+ /* Quit if we hit an incomplete type. Error is reported
+ by convert_arguments in c-typeck.c or cp/typeck.c. */
+ while (TREE_VALUE (formal_type) != void_type_node
+ && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
+ {
+ int parm_size
+ = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
+ /* Must round up to include padding. This is done the same
+ way as in store_one_arg. */
+ parm_size = ((parm_size + PARM_BOUNDARY - 1)
+ / PARM_BOUNDARY * PARM_BOUNDARY);
+ total += parm_size;
+ formal_type = TREE_CHAIN (formal_type);
+ }
+ }
+
+ /* Assume max of 8 base 10 digits in the suffix. */
+ newsym = xmalloc (1 + strlen (asmname) + 1 + 8 + 1);
+ sprintf (newsym, "%c%s@%d", FASTCALL_PREFIX, asmname, total/BITS_PER_UNIT);
+ return IDENTIFIER_POINTER (get_identifier (newsym));
+}
+
+/* Return string which is the former assembler name modified with a
+ suffix consisting of an atsign (@) followed by the number of bytes of
arguments */
-const char *
-gen_stdcall_suffix (decl)
- tree decl;
+static const char *
+gen_stdcall_suffix (tree decl)
{
int total = 0;
/* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
@@ -409,12 +456,15 @@ gen_stdcall_suffix (decl)
char *newsym;
if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
- if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
+ if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
== void_type_node)
{
tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
- while (TREE_VALUE (formal_type) != void_type_node)
+ /* Quit if we hit an incomplete type. Error is reported
+ by convert_arguments in c-typeck.c or cp/typeck.c. */
+ while (TREE_VALUE (formal_type) != void_type_node
+ && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
{
int parm_size
= TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
@@ -427,30 +477,28 @@ gen_stdcall_suffix (decl)
}
}
- newsym = xmalloc (strlen (asmname) + 10);
+ /* Assume max of 8 base 10 digits in the suffix. */
+ newsym = xmalloc (strlen (asmname) + 1 + 8 + 1);
sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT);
return IDENTIFIER_POINTER (get_identifier (newsym));
}
void
-i386_pe_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
+i386_pe_encode_section_info (tree decl, rtx rtl, int first)
{
- /* This bit is copied from i386.h. */
- if (optimize > 0 && TREE_CONSTANT (decl)
- && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
- {
- rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
- ? TREE_CST_RTL (decl) : DECL_RTL (decl));
- SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
- }
+ default_encode_section_info (decl, rtl, first);
if (TREE_CODE (decl) == FUNCTION_DECL)
- if (lookup_attribute ("stdcall",
- TYPE_ATTRIBUTES (TREE_TYPE (decl))))
- XEXP (DECL_RTL (decl), 0) =
- gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
+ {
+ if (lookup_attribute ("stdcall",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl))))
+ XEXP (DECL_RTL (decl), 0) =
+ gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
+ else if (lookup_attribute ("fastcall",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl))))
+ XEXP (DECL_RTL (decl), 0) =
+ gen_rtx (SYMBOL_REF, Pmode, gen_fastcall_suffix (decl));
+ }
/* Mark the decl so we can tell from the rtl whether the object is
dllexport'd or dllimport'd. This also handles dllexport/dllimport
@@ -462,8 +510,8 @@ i386_pe_encode_section_info (decl, first)
i386_pe_mark_dllimport (decl);
/* It might be that DECL has already been marked as dllimport, but a
subsequent definition nullified that. The attribute is gone but
- DECL_RTL still has (DLL_IMPORT_EXPORT_PREFIX)i._imp__foo. We need
- to remove that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
+ DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
+ that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
else if ((TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& DECL_RTL (decl) != NULL_RTX
@@ -473,12 +521,17 @@ i386_pe_encode_section_info (decl, first)
&& i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
{
const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
- tree idp = get_identifier (oldname + 9);
+
+ /* Remove DLL_IMPORT_PREFIX. */
+ tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
rtx newrtl = gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
- warning_with_decl (decl, "'%s' %s after being referenced with dllimport linkage.",
- (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
- ? "defined locally" : "redeclared without dllimport attribute");
+ if (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
+ warning ("%J'%D' defined locally after being "
+ "referenced with dllimport linkage", decl, decl);
+ else
+ warning ("%J'%D' redeclared without dllimport attribute "
+ "after being referenced with dllimport linkage", decl, decl);
XEXP (DECL_RTL (decl), 0) = newrtl;
@@ -489,14 +542,18 @@ i386_pe_encode_section_info (decl, first)
}
}
-/* Strip only the leading encoding, leaving the stdcall suffix. */
+/* Strip only the leading encoding, leaving the stdcall suffix and fastcall
+ prefix if it exists. */
const char *
-i386_pe_strip_name_encoding (str)
- const char *str;
+i386_pe_strip_name_encoding (const char *str)
{
- if (*str == DLL_IMPORT_EXPORT_PREFIX)
- str += 3;
+ if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
+ == 0)
+ str += strlen (DLL_IMPORT_PREFIX);
+ else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
+ == 0)
+ str += strlen (DLL_EXPORT_PREFIX);
if (*str == '*')
str += 1;
return str;
@@ -505,12 +562,11 @@ i386_pe_strip_name_encoding (str)
/* Also strip the stdcall suffix. */
const char *
-i386_pe_strip_name_encoding_full (str)
- const char *str;
+i386_pe_strip_name_encoding_full (const char *str)
{
const char *p;
const char *name = i386_pe_strip_name_encoding (str);
-
+
p = strchr (name, '@');
if (p)
return ggc_alloc_string (name, p - name);
@@ -518,10 +574,48 @@ i386_pe_strip_name_encoding_full (str)
return name;
}
+/* Output a reference to a label. Fastcall symbols are prefixed with @,
+ whereas symbols for functions using other calling conventions don't
+ have a prefix (unless they are marked dllimport or dllexport). */
+
+void i386_pe_output_labelref (FILE *stream, const char *name)
+{
+ if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
+ == 0)
+ /* A dll import */
+ {
+ if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
+ /* A dllimport fastcall symbol. */
+ {
+ fprintf (stream, "__imp_%s",
+ i386_pe_strip_name_encoding (name));
+ }
+ else
+ /* A dllimport non-fastcall symbol. */
+ {
+ fprintf (stream, "__imp__%s",
+ i386_pe_strip_name_encoding (name));
+ }
+ }
+ else if ((name[0] == FASTCALL_PREFIX)
+ || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX)
+ == 0
+ && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX)))
+ /* A fastcall symbol. */
+ {
+ fprintf (stream, "%s",
+ i386_pe_strip_name_encoding (name));
+ }
+ else
+ /* Everything else. */
+ {
+ fprintf (stream, "%s%s", USER_LABEL_PREFIX,
+ i386_pe_strip_name_encoding (name));
+ }
+}
+
void
-i386_pe_unique_section (decl, reloc)
- tree decl;
- int reloc;
+i386_pe_unique_section (tree decl, int reloc)
{
int len;
const char *name, *prefix;
@@ -533,7 +627,7 @@ i386_pe_unique_section (decl, reloc)
/* The object is put in, for example, section .text$foo.
The linker will then ultimately place them in .text
(everything from the $ on is stripped). Don't put
- read-only data in .rdata section to avoid a PE linker
+ read-only data in .rdata section to avoid a PE linker
bug when .rdata$* grouped sections are used in code
without a .rdata section. */
if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -559,7 +653,7 @@ i386_pe_unique_section (decl, reloc)
If the section has already been defined, to not allow it to have
different attributes, as (1) this is ambiguous since we're not seeing
all the declarations up front and (2) some assemblers (e.g. SVR4)
- do not recoginize section redefinitions. */
+ do not recognize section redefinitions. */
/* ??? This differs from the "standard" PE implementation in that we
handle the SHARED variable attribute. Should this be done for all
PE targets? */
@@ -567,10 +661,7 @@ i386_pe_unique_section (decl, reloc)
#define SECTION_PE_SHARED SECTION_MACH_DEP
unsigned int
-i386_pe_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+i386_pe_section_type_flags (tree decl, const char *name, int reloc)
{
static htab_t htab;
unsigned int flags;
@@ -608,25 +699,33 @@ i386_pe_section_type_flags (decl, name, reloc)
else
{
if (decl && **slot != flags)
- error_with_decl (decl, "%s causes a section type conflict");
+ error ("%J'%D' causes a section type conflict", decl, decl);
}
return flags;
}
void
-i386_pe_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+i386_pe_asm_named_section (const char *name, unsigned int flags)
{
char flagchars[8], *f = flagchars;
- if (flags & SECTION_CODE)
- *f++ = 'x';
- if (flags & SECTION_WRITE)
- *f++ = 'w';
- if (flags & SECTION_PE_SHARED)
- *f++ = 's';
+ if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
+ /* readonly data */
+ {
+ *f++ ='d'; /* This is necessary for older versions of gas. */
+ *f++ ='r';
+ }
+ else
+ {
+ if (flags & SECTION_CODE)
+ *f++ = 'x';
+ if (flags & SECTION_WRITE)
+ *f++ = 'w';
+ if (flags & SECTION_PE_SHARED)
+ *f++ = 's';
+ }
+
*f = '\0';
fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
@@ -654,10 +753,7 @@ i386_pe_asm_named_section (name, flags)
visible. */
void
-i386_pe_declare_function_type (file, name, public)
- FILE *file;
- const char *name;
- int public;
+i386_pe_declare_function_type (FILE *file, const char *name, int public)
{
fprintf (file, "\t.def\t");
assemble_name (file, name);
@@ -683,8 +779,7 @@ static struct extern_list *extern_head;
for it then. */
void
-i386_pe_record_external_function (name)
- const char *name;
+i386_pe_record_external_function (const char *name)
{
struct extern_list *p;
@@ -708,13 +803,11 @@ static struct export_list *export_head;
/* Assemble an export symbol entry. We need to keep a list of
these, so that we can output the export list at the end of the
assembly. We used to output these export symbols in each function,
- but that causes problems with GNU ld when the sections are
+ but that causes problems with GNU ld when the sections are
linkonce. */
void
-i386_pe_record_exported_symbol (name, is_data)
- const char *name;
- int is_data;
+i386_pe_record_exported_symbol (const char *name, int is_data)
{
struct export_list *p;
@@ -730,12 +823,11 @@ i386_pe_record_exported_symbol (name, is_data)
output the .drectve section. */
void
-i386_pe_asm_file_end (file)
- FILE *file;
+i386_pe_file_end (void)
{
struct extern_list *p;
- ix86_asm_file_end (file);
+ ix86_file_end ();
for (p = extern_head; p != NULL; p = p->next)
{
@@ -747,7 +839,8 @@ i386_pe_asm_file_end (file)
if (! TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (decl))
{
TREE_ASM_WRITTEN (decl) = 1;
- i386_pe_declare_function_type (file, p->name, TREE_PUBLIC (decl));
+ i386_pe_declare_function_type (asm_out_file, p->name,
+ TREE_PUBLIC (decl));
}
}
@@ -757,7 +850,7 @@ i386_pe_asm_file_end (file)
drectve_section ();
for (q = export_head; q != NULL; q = q->next)
{
- fprintf (file, "\t.ascii \" -export:%s%s\"\n",
+ fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
i386_pe_strip_name_encoding (q->name),
(q->is_data) ? ",data" : "");
}
OpenPOWER on IntegriCloud