aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-01-22 10:22:16 +0100
committerJakub Jelinek <jakub@redhat.com>2020-01-22 10:22:16 +0100
commitc892d8f58f6fed46c343bdb6dd4d365f08f801b8 (patch)
tree7df87fd8d1fbe74174e8d7070de1811d9ac9945d
parent44a9d801a7080d39658754ad603536da6cff2cd0 (diff)
downloadgcc-c892d8f58f6fed46c343bdb6dd4d365f08f801b8.zip
gcc-c892d8f58f6fed46c343bdb6dd4d365f08f801b8.tar.gz
gcc-c892d8f58f6fed46c343bdb6dd4d365f08f801b8.tar.bz2
i386: Fix up -fdollars-in-identifiers with identifiers starting with $ in -masm=att [PR91298]
In AT&T syntax leading $ is special, so if we have identifiers that start with dollar, we usually fail to assemble it (or assemble incorrectly). As mentioned in the PR, what works is wrapping the identifiers inside of parens, like: movl $($a), %eax leaq ($a)(,%rdi,4), %rax movl ($a)(%rip), %eax movl ($a)+16(%rip), %eax .globl $a .type $a, @object .size $a, 72 $a: .string "$a" .quad ($a) (this is x86_64 -fno-pic -O2). In some places ($a) is not accepted, like as .globl operand, in .type, .size, so the patch overrides ASM_OUTPUT_SYMBOL_REF rather than e.g. ASM_OUTPUT_LABELREF. I didn't want to duplicate what assemble_name is doing (following transparent aliases), so split assemble_name into two parts; just mere looking at the first character of a name before calling assemble_name wouldn't be good enough, a transparent alias could lead from a name not starting with $ to one starting with it and vice versa. 2020-01-22 Jakub Jelinek <jakub@redhat.com> PR target/91298 * output.h (assemble_name_resolve): Declare. * varasm.c (assemble_name_resolve): New function. (assemble_name): Use it. * config/i386/i386.h (ASM_OUTPUT_SYMBOL_REF): Define. * gcc.target/i386/pr91298-1.c: New test. * gcc.target/i386/pr91298-2.c: New test.
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/i386/i386.h25
-rw-r--r--gcc/output.h6
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91298-1.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91298-2.c5
-rw-r--r--gcc/varasm.c33
7 files changed, 82 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d338a4a..d3a7bc2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2020-01-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/91298
+ * output.h (assemble_name_resolve): Declare.
+ * varasm.c (assemble_name_resolve): New function.
+ (assemble_name): Use it.
+ * config/i386/i386.h (ASM_OUTPUT_SYMBOL_REF): Define.
+
2020-01-22 Joseph Myers <joseph@codesourcery.com>
* doc/sourcebuild.texi (Texinfo Manuals, Front End): Refer to
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 9774406..943e9a5 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2258,6 +2258,31 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
#define ASM_OUTPUT_FUNCTION_LABEL(FILE, NAME, DECL) \
ix86_asm_output_function_label ((FILE), (NAME), (DECL))
+/* A C statement (sans semicolon) to output a reference to SYMBOL_REF SYM.
+ If not defined, assemble_name will be used to output the name of the
+ symbol. This macro may be used to modify the way a symbol is referenced
+ depending on information encoded by TARGET_ENCODE_SECTION_INFO. */
+
+#ifndef ASM_OUTPUT_SYMBOL_REF
+#define ASM_OUTPUT_SYMBOL_REF(FILE, SYM) \
+ do { \
+ const char *name \
+ = assemble_name_resolve (XSTR (x, 0)); \
+ /* In -masm=att wrap identifiers that start with $ \
+ into parens. */ \
+ if (ASSEMBLER_DIALECT == ASM_ATT \
+ && name[0] == '$' \
+ && user_label_prefix[0] == '\0') \
+ { \
+ fputc ('(', (FILE)); \
+ assemble_name_raw ((FILE), name); \
+ fputc (')', (FILE)); \
+ } \
+ else \
+ assemble_name_raw ((FILE), name); \
+ } while (0)
+#endif
+
/* Under some conditions we need jump tables in the text section,
because the assembler cannot handle label differences between
sections. This is the case for x86_64 on Mach-O for example. */
diff --git a/gcc/output.h b/gcc/output.h
index d8d5497..eb253c5 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -237,6 +237,12 @@ extern void assemble_label (FILE *, const char *);
addition of an underscore). */
extern void assemble_name_raw (FILE *, const char *);
+/* Return NAME that should actually be emitted, looking through
+ transparent aliases. If NAME refers to an entity that is also
+ represented as a tree (like a function or variable), mark the entity
+ as referenced. */
+extern const char *assemble_name_resolve (const char *);
+
/* Like assemble_name_raw, but should be used when NAME might refer to
an entity that is also represented as a tree (like a function or
variable). If NAME does refer to such an entity, that entity will
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 552270d..a435fd1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2020-01-22 Jakub Jelinek <jakub@redhat.com>
+ PR target/91298
+ * gcc.target/i386/pr91298-1.c: New test.
+ * gcc.target/i386/pr91298-2.c: New test.
+
* gfortran.dg/gomp/target-parallel1.f90: New test.
* gfortran.dg/goacc/pr93329.f90: Enable commented out target parallel
test.
diff --git a/gcc/testsuite/gcc.target/i386/pr91298-1.c b/gcc/testsuite/gcc.target/i386/pr91298-1.c
new file mode 100644
index 0000000..45ef553
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91298-1.c
@@ -0,0 +1,14 @@
+/* PR target/91298 */
+/* { dg-do assemble } */
+/* { dg-options "-O2 -g -fdollars-in-identifiers" } */
+
+int $a[18];
+int *foo (void) { return &$a[0]; }
+int *bar (int x) { return &$a[x]; }
+int baz (void) { return $a[0]; }
+int qux (void) { return $a[4]; }
+int $quux (void) { return 1; }
+int corge (void) { return $quux (); }
+int grault (void) { return $quux () + 1; }
+typedef int (*fn) (void);
+fn foobar (void) { return $quux; }
diff --git a/gcc/testsuite/gcc.target/i386/pr91298-2.c b/gcc/testsuite/gcc.target/i386/pr91298-2.c
new file mode 100644
index 0000000..20e47ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91298-2.c
@@ -0,0 +1,5 @@
+/* PR target/91298 */
+/* { dg-do assemble { target fpic } } */
+/* { dg-options "-O2 -g -fdollars-in-identifiers -fpic" } */
+
+#include "pr91298-1.c"
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 498c5ff..dc6da6c 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2589,20 +2589,16 @@ assemble_name_raw (FILE *file, const char *name)
ASM_OUTPUT_LABELREF (file, name);
}
-/* Like assemble_name_raw, but should be used when NAME might refer to
- an entity that is also represented as a tree (like a function or
- variable). If NAME does refer to such an entity, that entity will
- be marked as referenced. */
-
-void
-assemble_name (FILE *file, const char *name)
+/* Return NAME that should actually be emitted, looking through
+ transparent aliases. If NAME refers to an entity that is also
+ represented as a tree (like a function or variable), mark the entity
+ as referenced. */
+const char *
+assemble_name_resolve (const char *name)
{
- const char *real_name;
- tree id;
+ const char *real_name = targetm.strip_name_encoding (name);
+ tree id = maybe_get_identifier (real_name);
- real_name = targetm.strip_name_encoding (name);
-
- id = maybe_get_identifier (real_name);
if (id)
{
tree id_orig = id;
@@ -2614,7 +2610,18 @@ assemble_name (FILE *file, const char *name)
gcc_assert (! TREE_CHAIN (id));
}
- assemble_name_raw (file, name);
+ return name;
+}
+
+/* Like assemble_name_raw, but should be used when NAME might refer to
+ an entity that is also represented as a tree (like a function or
+ variable). If NAME does refer to such an entity, that entity will
+ be marked as referenced. */
+
+void
+assemble_name (FILE *file, const char *name)
+{
+ assemble_name_raw (file, assemble_name_resolve (name));
}
/* Allocate SIZE bytes writable static space with a gensym name