aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386/winnt.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2007-03-29 14:54:35 -0700
committerRichard Henderson <rth@gcc.gnu.org>2007-03-29 14:54:35 -0700
commitda489f7340623783872629a4ebd595d93fc3dced (patch)
treeeb98f4ede31001adc419d6556b98962ff353afb5 /gcc/config/i386/winnt.c
parent0c9bce0b5cfe0a037bdabd00cc783a37ff1f159c (diff)
downloadgcc-da489f7340623783872629a4ebd595d93fc3dced.zip
gcc-da489f7340623783872629a4ebd595d93fc3dced.tar.gz
gcc-da489f7340623783872629a4ebd595d93fc3dced.tar.bz2
varasm.c (initializer_constant_valid_p): Don't deny DECL_DLLIMPORT_P on functions.
* varasm.c (initializer_constant_valid_p): Don't deny DECL_DLLIMPORT_P on functions. * config/i386/cygming.h: Remove function declarations. (SUBTARGET_ENCODE_SECTION_INFO): Don't undef first. (ASM_OUTPUT_LABELREF): Remove. (COMMON_ASM_OP): Remove. (ASM_OUTPUT_COMMON): Remove. (ASM_OUTPUT_ALIGNED_DECL_COMMON): New. (ASM_DECLARE_OBJECT_NAME): Use i386_pe_maybe_record_exported_symbol. (ASM_DECLARE_FUNCTION_NAME): Likewise. * config/i386/i386-interix.h (SUBTARGET_ENCODE_SECTION_INFO): Rename from TARGET_ENCODE_SECTION_INFO. * config/i386/netware.h: Likewise. * config/i386/i386-protos.h: Update. * config/i386/i386.c (ix86_function_ok_for_sibcall): Turn ifdef of TARGET_DLLIMPORT_DECL_ATTRIBUTES into straight if. (legitimate_constant_p): Reject dllimports. (dllimport_map, get_dllimport_decl): New. (legitimize_dllimport_symbol): New. (legitimize_address, ix86_expand_move): Use it. (TARGET_BINDS_LOCAL_P): Redefine for TARGET_DLLIMPORT_DECL_ATTRIBUTES. * config/i386/i386.h (DLL_IMPORT_EXPORT_PREFIX): Remove. (SYMBOL_FLAG_DLLIMPORT, SYMBOL_REF_DLLIMPORT_P): New. (SYMBOL_FLAG_DLLEXPORT, SYMBOL_REF_DLLEXPORT_P): New. * config/i386/predicates.md (constant_call_address_operand): Only accept symbols; reject dllimport_p symbols. * config/i386/uwin.h (ASM_DECLARE_FUNCTION_NAME): Use i386_pe_maybe_record_exported_symbol. * config/i386/winnt.c (DLL_IMPORT_PREFIX, DLL_EXPORT_PREFIX): Remove. (i386_pe_determine_dllexport_p): Rename from i386_pe_dllexport_p. (i386_pe_determine_dllimport_p): Rename from i386_pe_dllimport_p; trust the setting of DECL_DLLIMPORT_P. (i386_pe_dllexport_name_p, i386_pe_dllimport_name_p): Remove. (i386_pe_mark_dllexport, i386_pe_mark_dllimport): Remove. (gen_stdcall_or_fastcall_suffix): Return NULL if no change required; tidy the argument scanning loop. (i386_pe_encode_section_info): Set SYMBOL_FLAG_DLLIMPORT and SYMBOL_FLAG_DLLEXPORT in SYMBOL_REF_FLAGS. (i386_pe_strip_name_encoding): Remove. (i386_pe_binds_local_p): New. (i386_pe_strip_name_encoding_full): Use default_strip_name_encoding. (i386_pe_output_labelref): Remove. (i386_pe_asm_output_aligned_decl_common): New. (i386_pe_maybe_record_exported_symbol): Rename from i386_pe_record_exported_symbol; check for dllexported symbols. From-SVN: r123344
Diffstat (limited to 'gcc/config/i386/winnt.c')
-rw-r--r--gcc/config/i386/winnt.c466
1 files changed, 171 insertions, 295 deletions
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index a46fc5b..a36fd08 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -34,6 +34,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "toplev.h"
#include "hashtab.h"
#include "ggc.h"
+#include "target.h"
/* i386/PE specific attribute support.
@@ -46,22 +47,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
multiple times.
*/
-static tree associated_type (tree);
-static tree gen_stdcall_or_fastcall_suffix (tree, bool);
-static bool i386_pe_dllexport_p (tree);
-static bool 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 "shared" attribute;
arguments as in struct attribute_spec.handler. */
tree
@@ -108,67 +93,59 @@ ix86_handle_selectany_attribute (tree *node, tree name,
static tree
associated_type (tree decl)
{
- return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
- ? DECL_CONTEXT (decl) : NULL_TREE;
+ return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
+ ? DECL_CONTEXT (decl) : NULL_TREE);
}
-
-/* Return true if DECL is a dllexport'd object. */
+/* Return true if DECL should be a dllexport'd object. */
static bool
-i386_pe_dllexport_p (tree decl)
+i386_pe_determine_dllexport_p (tree decl)
{
- if (TREE_CODE (decl) != VAR_DECL
- && TREE_CODE (decl) != FUNCTION_DECL)
+ tree assoc;
+
+ if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
return false;
if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
return true;
/* Also mark class members of exported classes with dllexport. */
- if (associated_type (decl)
- && lookup_attribute ("dllexport",
- TYPE_ATTRIBUTES (associated_type (decl))))
+ assoc = associated_type (decl);
+ if (assoc && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (assoc)))
return i386_pe_type_dllexport_p (decl);
return false;
}
+/* Return true if DECL should be a dllimport'd object. */
+
static bool
-i386_pe_dllimport_p (tree decl)
+i386_pe_determine_dllimport_p (tree decl)
{
- if (TREE_CODE (decl) != VAR_DECL
- && TREE_CODE (decl) != FUNCTION_DECL)
+ tree assoc;
+
+ if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
return false;
/* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P flag.
We may need to override an earlier decision. */
- if (DECL_DLLIMPORT_P (decl)
- && lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)))
- {
- /* Make a final check to see if this is a definition before we generate
- RTL for an indirect reference. */
- if (!DECL_EXTERNAL (decl))
- {
- error ("%q+D: definition is marked as dllimport", decl);
- DECL_DLLIMPORT_P (decl) = 0;
- return false;
- }
- return true;
- }
+ if (DECL_DLLIMPORT_P (decl))
+ return true;
+
/* The DECL_DLLIMPORT_P flag was set for decls in the class definition
by targetm.cxx.adjust_class_at_definition. Check again to emit
warnings if the class attribute has been overridden by an
out-of-class definition. */
- else if (associated_type (decl)
- && lookup_attribute ("dllimport",
- TYPE_ATTRIBUTES (associated_type (decl))))
+ assoc = associated_type (decl);
+ if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc)))
return i386_pe_type_dllimport_p (decl);
return false;
}
/* Handle the -mno-fun-dllimport target switch. */
+
bool
i386_pe_valid_dllimport_attribute_p (tree decl)
{
@@ -177,247 +154,157 @@ i386_pe_valid_dllimport_attribute_p (tree decl)
return true;
}
-/* Return nonzero if SYMBOL is marked as being dllexport'd. */
-
-int
-i386_pe_dllexport_name_p (const char *symbol)
-{
- 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 (const char *symbol)
-{
- 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 (e.g.: dllimport). */
-
-static void
-i386_pe_mark_dllexport (tree decl)
-{
- const char *oldname;
- char *newname;
- rtx rtlname;
- rtx symref;
- tree idp;
-
- rtlname = XEXP (DECL_RTL (decl), 0);
- if (GET_CODE (rtlname) == MEM)
- rtlname = XEXP (rtlname, 0);
- gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
- oldname = XSTR (rtlname, 0);
- if (i386_pe_dllimport_name_p (oldname))
- {
- warning (0, "inconsistent dll linkage for %q+D, dllexport assumed",
- decl);
- /* Remove DLL_IMPORT_PREFIX. */
- oldname += strlen (DLL_IMPORT_PREFIX);
- }
- else if (i386_pe_dllexport_name_p (oldname))
- return; /* already done */
-
- 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
- and compare the string's addresses to see if two symbols are
- identical. */
- idp = get_identifier (newname);
-
- symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
- SET_SYMBOL_REF_DECL (symref, decl);
- XEXP (DECL_RTL (decl), 0) = symref;
-}
-
-/* Mark a DECL as being dllimport'd. */
-
-static void
-i386_pe_mark_dllimport (tree decl)
-{
- const char *oldname;
- char *newname;
- tree idp;
- rtx rtlname, newrtl;
- rtx symref;
-
- rtlname = XEXP (DECL_RTL (decl), 0);
- if (GET_CODE (rtlname) == MEM)
- rtlname = XEXP (rtlname, 0);
- gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
- oldname = XSTR (rtlname, 0);
- if (i386_pe_dllexport_name_p (oldname))
- {
- error ("%qs declared as both exported to and imported from a DLL",
- IDENTIFIER_POINTER (DECL_NAME (decl)));
- return;
- }
- else if (i386_pe_dllimport_name_p (oldname))
- {
- /* Already done, but do a sanity check to prevent assembler
- errors. */
- gcc_assert (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
- && DECL_DLLIMPORT_P (decl));
- return;
- }
-
- 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
- and compare the string's addresses to see if two symbols are
- identical. */
- idp = get_identifier (newname);
-
- symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
- SET_SYMBOL_REF_DECL (symref, decl);
- newrtl = gen_rtx_MEM (Pmode,symref);
- XEXP (DECL_RTL (decl), 0) = newrtl;
-
- DECL_DLLIMPORT_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
- arguments. If FASTCALL is true, also add the FASTCALL_PREFIX. */
+ arguments. If FASTCALL is true, also add the FASTCALL_PREFIX.
+ Return NULL if no change required. */
static tree
gen_stdcall_or_fastcall_suffix (tree decl, bool fastcall)
{
- int total = 0;
- /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
- of DECL_ASSEMBLER_NAME. */
- const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- char *newsym;
- char *p;
+ HOST_WIDE_INT total = 0;
+ const char *asm_str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ char *new_str, *p;
tree formal_type;
/* Do not change the identifier if a verbatim asmspec or already done. */
- if (*asmname == '*' || strchr (asmname, '@'))
- return DECL_ASSEMBLER_NAME (decl);
+ if (*asm_str == '*' || strchr (asm_str, '@'))
+ return NULL_TREE;
formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
if (formal_type != NULL_TREE)
- {
- /* These attributes are ignored for variadic functions in
- i386.c:ix86_return_pops_args. For compatibility with MS
- compiler do not add @0 suffix here. */
- if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
- return DECL_ASSEMBLER_NAME (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);\
- }
- }
+ while (1)
+ {
+ HOST_WIDE_INT parm_size;
+ HOST_WIDE_INT parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
+
+ /* We got to the end of the list without seeing void_list_node,
+ which means the function is variadic. The suffix is to be
+ ignored in that case. */
+ if (formal_type == NULL_TREE)
+ return NULL_TREE;
+
+ /* End of arguments, non-varargs marker. */
+ if (formal_type == void_list_node)
+ break;
+
+ /* Quit if we hit an incomplete type. Error is reported
+ by convert_arguments in c-typeck.c or cp/typeck.c. */
+ parm_size = int_size_in_bytes (TREE_VALUE (formal_type));
+ if (parm_size < 0)
+ break;
+
+ /* Must round up to include padding. This is done the same
+ way as in store_one_arg. */
+ parm_size = ((parm_size + parm_boundary_bytes - 1)
+ / parm_boundary_bytes * parm_boundary_bytes);
+ total += parm_size;
+
+ formal_type = TREE_CHAIN (formal_type);
+ }
/* Assume max of 8 base 10 digits in the suffix. */
- newsym = alloca (1 + strlen (asmname) + 1 + 8 + 1);
- p = newsym;
+ p = new_str = alloca (1 + strlen (asm_str) + 1 + 8 + 1);
if (fastcall)
*p++ = FASTCALL_PREFIX;
- sprintf (p, "%s@%d", asmname, total/BITS_PER_UNIT);
- return get_identifier (newsym);
+ sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, asm_str, total);
+
+ return get_identifier (new_str);
}
void
i386_pe_encode_section_info (tree decl, rtx rtl, int first)
{
+ rtx symbol;
+ int flags;
+
+ /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above. */
default_encode_section_info (decl, rtl, first);
- if (first && TREE_CODE (decl) == FUNCTION_DECL)
+ /* Careful not to prod global register variables. */
+ if (!MEM_P (rtl))
+ return;
+
+ symbol = XEXP (rtl, 0);
+ gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
+
+ switch (TREE_CODE (decl))
{
- tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
- tree newid = NULL_TREE;
-
- if (lookup_attribute ("stdcall", type_attributes))
- newid = gen_stdcall_or_fastcall_suffix (decl, false);
- else if (lookup_attribute ("fastcall", type_attributes))
- newid = gen_stdcall_or_fastcall_suffix (decl, true);
- if (newid != NULL_TREE)
+ case FUNCTION_DECL:
+ if (first)
{
- rtx rtlname = XEXP (rtl, 0);
- if (GET_CODE (rtlname) == MEM)
- rtlname = XEXP (rtlname, 0);
- XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
- /* These attributes must be present on first declaration,
- change_decl_assembler_name will warn if they are added
- later and the decl has been referenced, but duplicate_decls
- should catch the mismatch before this is called. */
- change_decl_assembler_name (decl, newid);
+ tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+ tree newid = NULL_TREE;
+
+ if (lookup_attribute ("stdcall", type_attributes))
+ newid = gen_stdcall_or_fastcall_suffix (decl, false);
+ else if (lookup_attribute ("fastcall", type_attributes))
+ newid = gen_stdcall_or_fastcall_suffix (decl, true);
+ if (newid != NULL_TREE)
+ {
+ XSTR (symbol, 0) = IDENTIFIER_POINTER (newid);
+ /* These attributes must be present on first declaration,
+ change_decl_assembler_name will warn if they are added
+ later and the decl has been referenced, but duplicate_decls
+ should catch the mismatch before this is called. */
+ change_decl_assembler_name (decl, newid);
+ }
}
- }
+ break;
- else if (TREE_CODE (decl) == VAR_DECL
- && lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
- {
- if (DECL_INITIAL (decl)
- /* If an object is initialized with a ctor, the static
- initialization and destruction code for it is present in
- each unit defining the object. The code that calls the
- ctor is protected by a link-once guard variable, so that
- the object still has link-once semantics, */
- || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
- make_decl_one_only (decl);
- else
- error ("%q+D:'selectany' attribute applies only to initialized objects",
- decl);
+ case VAR_DECL:
+ if (lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
+ {
+ if (DECL_INITIAL (decl)
+ /* If an object is initialized with a ctor, the static
+ initialization and destruction code for it is present in
+ each unit defining the object. The code that calls the
+ ctor is protected by a link-once guard variable, so that
+ the object still has link-once semantics, */
+ || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
+ make_decl_one_only (decl);
+ else
+ error ("%q+D:'selectany' attribute applies only to "
+ "initialized objects", decl);
+ }
+ break;
+
+ default:
+ return;
}
/* Mark the decl so we can tell from the rtl whether the object is
dllexport'd or dllimport'd. tree.c: merge_dllimport_decl_attributes
handles dllexport/dllimport override semantics. */
-
- if (i386_pe_dllexport_p (decl))
- i386_pe_mark_dllexport (decl);
- else if (i386_pe_dllimport_p (decl))
- i386_pe_mark_dllimport (decl);
- /* It might be that DECL has been declared as dllimport, but a
- subsequent definition nullified that. Assert that
- tree.c: merge_dllimport_decl_attributes has removed the attribute
- before the RTL name was marked with the DLL_IMPORT_PREFIX. */
- else
- gcc_assert (!((TREE_CODE (decl) == FUNCTION_DECL
- || TREE_CODE (decl) == VAR_DECL)
- && rtl != NULL_RTX
- && GET_CODE (rtl) == MEM
- && GET_CODE (XEXP (rtl, 0)) == MEM
- && GET_CODE (XEXP (XEXP (rtl, 0), 0)) == SYMBOL_REF
- && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (rtl, 0), 0), 0))));
+ flags = (SYMBOL_REF_FLAGS (symbol) &
+ ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT));
+ if (i386_pe_determine_dllexport_p (decl))
+ flags |= SYMBOL_FLAG_DLLEXPORT;
+ else if (i386_pe_determine_dllimport_p (decl))
+ {
+ flags |= SYMBOL_FLAG_DLLIMPORT;
+ /* If we went through the associated_type path, this won't already
+ be set. Though, frankly, this seems wrong, and should be fixed
+ elsewhere. */
+ if (!DECL_DLLIMPORT_P (decl))
+ {
+ DECL_DLLIMPORT_P (decl) = 1;
+ flags &= ~SYMBOL_FLAG_LOCAL;
+ }
+ }
+ SYMBOL_REF_FLAGS (symbol) = flags;
}
-/* Strip only the leading encoding, leaving the stdcall suffix and fastcall
- prefix if it exists. */
-
-const char *
-i386_pe_strip_name_encoding (const char *str)
+bool
+i386_pe_binds_local_p (tree exp)
{
- 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;
+ /* PE does not do dynamic binding. Indeed, the only kind of
+ non-local reference comes from a dllimport'd symbol. */
+ if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
+ && DECL_DLLIMPORT_P (exp))
+ return false;
+
+ return true;
}
/* Also strip the fastcall prefix and stdcall suffix. */
@@ -426,7 +313,7 @@ const char *
i386_pe_strip_name_encoding_full (const char *str)
{
const char *p;
- const char *name = i386_pe_strip_name_encoding (str);
+ const char *name = default_strip_name_encoding (str);
/* Strip leading '@' on fastcall symbols. */
if (*name == '@')
@@ -440,46 +327,6 @@ i386_pe_strip_name_encoding_full (const char *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 (tree decl, int reloc)
{
@@ -612,6 +459,29 @@ i386_pe_asm_named_section (const char *name, unsigned int flags,
(discard ? "discard" : "same_size"));
}
}
+
+void
+i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl,
+ const char *name, HOST_WIDE_INT size,
+ HOST_WIDE_INT align ATTRIBUTE_UNUSED)
+{
+ HOST_WIDE_INT rounded;
+
+ /* Compute as in assemble_noswitch_variable, since we don't actually
+ support aligned common. */
+ rounded = size ? size : 1;
+ rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
+ rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
+ * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
+
+ i386_pe_maybe_record_exported_symbol (decl, name, 1);
+
+ fprintf (stream, "\t.comm\t");
+ assemble_name (stream, name);
+ fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
+ " " HOST_WIDE_INT_PRINT_DEC "\n",
+ rounded, size);
+}
/* The Microsoft linker requires that every function be marked as
DT_FCN. When using gas on cygwin, we must emit appropriate .type
@@ -682,10 +552,16 @@ static GTY(()) struct export_list *export_head;
linkonce. */
void
-i386_pe_record_exported_symbol (const char *name, int is_data)
+i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
{
+ rtx symbol;
struct export_list *p;
+ symbol = XEXP (DECL_RTL (decl), 0);
+ gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
+ if (!SYMBOL_REF_DLLEXPORT_P (symbol))
+ return;
+
p = (struct export_list *) ggc_alloc (sizeof *p);
p->next = export_head;
p->name = name;
@@ -727,8 +603,8 @@ i386_pe_file_end (void)
for (q = export_head; q != NULL; q = q->next)
{
fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
- i386_pe_strip_name_encoding (q->name),
- (q->is_data) ? ",data" : "");
+ targetm.strip_name_encoding (q->name),
+ (q->is_data ? ",data" : ""));
}
}
}