aboutsummaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorRamana Radhakrishnan <ramana@gcc.gnu.org>2015-10-20 10:36:33 +0000
committerRamana Radhakrishnan <ramana@gcc.gnu.org>2015-10-20 10:36:33 +0000
commit75d363a0428aa9a1f73c4c995cba57e92b93ccda (patch)
treef7c1c17805044d1034e23b5428edc324161d3db3 /gcc/varasm.c
parent04b32ed7444af274054b00d8bd06f26819c97c65 (diff)
downloadgcc-75d363a0428aa9a1f73c4c995cba57e92b93ccda.zip
gcc-75d363a0428aa9a1f73c4c995cba57e92b93ccda.tar.gz
gcc-75d363a0428aa9a1f73c4c995cba57e92b93ccda.tar.bz2
Fix VTV for targets with section anchors.
2015-10-20 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> PR other/67868 * varasm.c (assemble_variable): Move special vtv handling to.. (handle_vtv_comdat_sections): .. here. New function. (output_object_block): Handle vtv sections. From-SVN: r229043
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c112
1 files changed, 63 insertions, 49 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index ff9d271..2b6da59 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -127,6 +127,7 @@ static void asm_output_aligned_bss (FILE *, tree, const char *,
#endif /* BSS_SECTION_ASM_OP */
static void mark_weak (tree);
static void output_constant_pool (const char *, tree);
+static void handle_vtv_comdat_section (section *, const_tree);
/* Well-known sections, each one associated with some sort of *_ASM_OP. */
section *text_section;
@@ -2230,56 +2231,10 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
assemble_noswitch_variable (decl, name, sect, align);
else
{
- /* The following bit of code ensures that vtable_map
- variables are not only in the comdat section, but that
- each variable has its own unique comdat name. If this
- code is removed, the variables end up in the same section
- with a single comdat name.
-
- FIXME: resolve_unique_section needs to deal better with
- decls with both DECL_SECTION_NAME and DECL_ONE_ONLY. Once
- that is fixed, this if-else statement can be replaced with
- a single call to "switch_to_section (sect)". */
+ /* Special-case handling of vtv comdat sections. */
if (sect->named.name
&& (strcmp (sect->named.name, ".vtable_map_vars") == 0))
- {
-#if defined (OBJECT_FORMAT_ELF)
- targetm.asm_out.named_section (sect->named.name,
- sect->named.common.flags
- | SECTION_LINKONCE,
- DECL_NAME (decl));
- in_section = sect;
-#elif defined (TARGET_PECOFF)
- /* Neither OBJECT_FORMAT_PE, nor OBJECT_FORMAT_COFF is set here.
- Therefore the following check is used.
- In case a the target is PE or COFF a comdat group section
- is created, e.g. .vtable_map_vars$foo. The linker places
- everything in .vtable_map_vars at the end.
-
- A fix could be made in
- gcc/config/i386/winnt.c: i386_pe_unique_section. */
- if (TARGET_PECOFF)
- {
- char *name;
-
- if (TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE)
- name = ACONCAT ((sect->named.name, "$",
- IDENTIFIER_POINTER (DECL_NAME (decl)), NULL));
- else
- name = ACONCAT ((sect->named.name, "$",
- IDENTIFIER_POINTER (DECL_COMDAT_GROUP (DECL_NAME (decl))),
- NULL));
-
- targetm.asm_out.named_section (name,
- sect->named.common.flags
- | SECTION_LINKONCE,
- DECL_NAME (decl));
- in_section = sect;
- }
-#else
- switch_to_section (sect);
-#endif
- }
+ handle_vtv_comdat_section (sect, decl);
else
switch_to_section (sect);
if (align > BITS_PER_UNIT)
@@ -7330,7 +7285,14 @@ output_object_block (struct object_block *block)
/* Switch to the section and make sure that the first byte is
suitably aligned. */
- switch_to_section (block->sect);
+ /* Special case VTV comdat sections similar to assemble_variable. */
+ if (SECTION_STYLE (block->sect) == SECTION_NAMED
+ && block->sect->named.name
+ && (strcmp (block->sect->named.name, ".vtable_map_vars") == 0))
+ handle_vtv_comdat_section (block->sect, block->sect->named.decl);
+ else
+ switch_to_section (block->sect);
+
assemble_align (block->alignment);
/* Define the values of all anchors relative to the current section
@@ -7773,4 +7735,56 @@ default_asm_output_ident_directive (const char *ident_str)
fprintf (asm_out_file, "%s\"%s\"\n", ident_asm_op, ident_str);
}
+
+/* This function ensures that vtable_map variables are not only
+ in the comdat section, but that each variable has its own unique
+ comdat name. Without this the variables end up in the same section
+ with a single comdat name.
+
+ FIXME: resolve_unique_section needs to deal better with
+ decls with both DECL_SECTION_NAME and DECL_ONE_ONLY. Once
+ that is fixed, this if-else statement can be replaced with
+ a single call to "switch_to_section (sect)". */
+
+static void
+handle_vtv_comdat_section (section *sect, const_tree decl)
+{
+#if defined (OBJECT_FORMAT_ELF)
+ targetm.asm_out.named_section (sect->named.name,
+ sect->named.common.flags
+ | SECTION_LINKONCE,
+ DECL_NAME (decl));
+ in_section = sect;
+#elif defined (TARGET_PECOFF)
+ /* Neither OBJECT_FORMAT_PE, nor OBJECT_FORMAT_COFF is set here.
+ Therefore the following check is used.
+ In case a the target is PE or COFF a comdat group section
+ is created, e.g. .vtable_map_vars$foo. The linker places
+ everything in .vtable_map_vars at the end.
+
+ A fix could be made in
+ gcc/config/i386/winnt.c: i386_pe_unique_section. */
+ if (TARGET_PECOFF)
+ {
+ char *name;
+
+ if (TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE)
+ name = ACONCAT ((sect->named.name, "$",
+ IDENTIFIER_POINTER (DECL_NAME (decl)), NULL));
+ else
+ name = ACONCAT ((sect->named.name, "$",
+ IDENTIFIER_POINTER (DECL_COMDAT_GROUP (DECL_NAME (decl))),
+ NULL));
+
+ targetm.asm_out.named_section (name,
+ sect->named.common.flags
+ | SECTION_LINKONCE,
+ DECL_NAME (decl));
+ in_section = sect;
+ }
+#else
+ switch_to_section (sect);
+#endif
+}
+
#include "gt-varasm.h"