From 362b4eebeb56e76bb3045b92be6b2304f86d06c4 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sun, 5 Jul 2015 08:58:28 -0700
Subject: [PATCH] Output ELF symbol type for undefined symbols
Update default_elf_asm_output_external to also output symbol type to
help ELF linker properly issue diagnostic message. We don't output
symbol type for reference to external TLS symbol since assembler will
generate TLS symbol type based on TLS relocation and Solaris assembler
only supports the @tls_obj type directive, not the @tls_object type
directive used by GNU assmbler, which doesn't understand the @tls_obj
type directive.
gcc/
PR target/35514
* varasm.c (default_elf_asm_output_external): Also output symbol
type.
gcc/testsuite/
PR target/35514
* g++.dg/fstack-protector-strong.C: Adjust scan-assembler-times
for ELF targets.
* g++.dg/opt/devirt2.C: Likewise.
* g++.dg/pr49718.C: Likewise.
* g++.dg/stackprotectexplicit2.C : Likewise.
* gcc.dg/fstack-protector-strong.c: Likewise.
* gcc.dg/tree-ssa/loop-1.c: Likewise.
* gcc.target/i386/memcpy-strategy-3.c: Likewise.
* gcc.target/i386/memset-strategy-1.c: Likewise.
* gfortran.dg/bind_c_array_params_2.f90: Likewise.
* gcc.dg/pr35514-1.c: New file.
* gcc.dg/pr35514-2.c: Likewise.
* lib/target-supports.exp (check_effective_target_elf): New.
---
gcc/testsuite/g++.dg/fstack-protector-strong.C | 3 ++-
gcc/testsuite/g++.dg/opt/devirt2.C | 3 ++-
gcc/testsuite/g++.dg/pr49718.C | 3 ++-
gcc/testsuite/g++.dg/stackprotectexplicit2.C | 3 ++-
gcc/testsuite/gcc.dg/fstack-protector-strong.c | 3 ++-
gcc/testsuite/gcc.dg/pr35514-1.c | 16 ++++++++++++++++
gcc/testsuite/gcc.dg/pr35514-2.c | 14 ++++++++++++++
gcc/testsuite/gcc.dg/tree-ssa/loop-1.c | 3 ++-
gcc/testsuite/gcc.target/i386/memcpy-strategy-3.c | 3 ++-
gcc/testsuite/gcc.target/i386/memset-strategy-1.c | 3 ++-
.../gfortran.dg/bind_c_array_params_2.f90 | 3 ++-
gcc/testsuite/lib/target-supports.exp | 20 ++++++++++++++++++++
gcc/varasm.c | 22 +++++++++++++++++-----
13 files changed, 85 insertions(+), 14 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr35514-1.c
create mode 100644 gcc/testsuite/gcc.dg/pr35514-2.c
@@ -85,4 +85,5 @@ int foo7 (B *p)
return p->return_slot ().a1;
}
-/* { dg-final { scan-assembler-times "stack_chk_fail" 7 } } */
+/* { dg-final { scan-assembler-times "stack_chk_fail" 8 { target elf } } } */
+/* { dg-final { scan-assembler-times "stack_chk_fail" 7 { target { ! elf } } } } */
@@ -5,7 +5,8 @@
// { dg-additional-options "-mshort-calls" {target epiphany-*-*} }
// Using -mno-abicalls avoids a R_MIPS_JALR .reloc.
// { dg-additional-options "-mno-abicalls" { target mips*-*-* } }
-// { dg-final { scan-assembler-times "xyzzy" 2 { target { ! { alpha*-*-* hppa*-*-* ia64*-*-hpux* sparc*-*-* *-*-mingw* } } } } }
+// { dg-final { scan-assembler-times "xyzzy" 2 { target { ! elf } && target { ! { alpha*-*-* hppa*-*-* ia64*-*-hpux* sparc*-*-* *-*-mingw* } } } } }
+// { dg-final { scan-assembler-times "xyzzy" 3 { target { elf && { ! { alpha*-*-* hppa*-*-* ia64*-*-hpux* sparc*-*-* } } } } } }
// For *-*-mingw* there is additionally one .def match
// { dg-final { scan-assembler-times "xyzzy" 3 { target *-*-mingw* } } }
// The IA64 and HPPA compilers generate external declarations in addition
@@ -2,7 +2,8 @@
/* { dg-options "-O2 -finstrument-functions" } */
/* { dg-additional-options "-mno-explicit-relocs" { target alpha*-*-* } } */
/* { dg-additional-options "-mno-relax-pic-calls" { target mips*-*-* } } */
-/* { dg-final { scan-assembler-times "__cyg_profile_func_enter" 1 { target { ! { hppa*-*-hpux* } } } } } */
+/* { dg-final { scan-assembler-times "__cyg_profile_func_enter" 1 { target { ! elf } && target { ! { hppa*-*-hpux* } } } } } */
+/* { dg-final { scan-assembler-times "__cyg_profile_func_enter" 2 { target { elf && { ! { hppa*-*-hpux* } } } } } } */
/* { dg-final { scan-assembler-times "__cyg_profile_func_enter,%r" 1 { target hppa*-*-hpux* } } } */
#define NOINSTR __attribute__((no_instrument_function))
@@ -24,4 +24,5 @@ int __attribute__((stack_protect)) c()
}
-/* { dg-final { scan-assembler-times "stack_chk_fail" 2 } } */
\ No newline at end of file
+/* { dg-final { scan-assembler-times "stack_chk_fail" 3 { target elf } } } */
+/* { dg-final { scan-assembler-times "stack_chk_fail" 2 { target { ! elf } } } } */
@@ -154,4 +154,5 @@ void foo12 ()
global3 ();
}
-/* { dg-final { scan-assembler-times "stack_chk_fail" 12 } } */
+/* { dg-final { scan-assembler-times "stack_chk_fail" 13 { target elf } } } */
+/* { dg-final { scan-assembler-times "stack_chk_fail" 12 { target { ! elf } } } } */
new file mode 100644
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { elf } } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".type\[^\\n\]*object, \(%|@\)object" } } */
+/* { dg-final { scan-assembler ".type\[^\\n\]*function, \(%|@\)function" } } */
+
+/* Verify that we generate proper symbol types for external reference. */
+
+extern int object;
+void function (void);
+
+int
+foo (void)
+{
+ function ();
+ return object;
+}
new file mode 100644
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { elf } } } */
+/* { dg-require-effective-target tls } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not ".type\[^\\n\]*object, \(%|@\)object" } } */
+
+/* Verify that we generate proper symbol types for external reference. */
+
+extern __thread int object;
+
+int
+foo (void)
+{
+ return object;
+}
@@ -46,7 +46,8 @@ int xxx(void)
/* CRIS keeps the address in a register. */
/* m68k sometimes puts the address in a register, depending on CPU and PIC. */
-/* { dg-final { scan-assembler-times "foo" 5 { xfail hppa*-*-* ia64*-*-* sh*-*-* cris-*-* crisv32-*-* fido-*-* m68k-*-* i?86-*-mingw* i?86-*-cygwin* x86_64-*-mingw* visium-*-* } } } */
+/* { dg-final { scan-assembler-times "foo" 5 { target { ! elf } xfail hppa*-*-* ia64*-*-* sh*-*-* cris-*-* crisv32-*-* fido-*-* m68k-*-* i?86-*-mingw* i?86-*-cygwin* x86_64-*-mingw* visium-*-* } } } */
+/* { dg-final { scan-assembler-times "foo" 6 { target elf xfail hppa*-*-* ia64*-*-* sh*-*-* cris-*-* crisv32-*-* fido-*-* m68k-*-* visium-*-* } } } */
/* { dg-final { scan-assembler-times "foo,%r" 5 { target hppa*-*-* } } } */
/* { dg-final { scan-assembler-times "= foo" 5 { target ia64*-*-* } } } */
/* { dg-final { scan-assembler-times "call\[ \t\]*_foo" 5 { target i?86-*-mingw* i?86-*-cygwin* } } } */
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:2000:align,libcall:-1:align" } */
-/* { dg-final { scan-assembler-times "memcpy" 2 } } */
+/* { dg-final { scan-assembler-times "memcpy" 3 { target elf } } } */
+/* { dg-final { scan-assembler-times "memcpy" 2 { target { ! elf } } } } */
char a[2048];
char b[2048];
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -march=atom -mmemset-strategy=libcall:-1:align" } */
-/* { dg-final { scan-assembler-times "memset" 2 } } */
+/* { dg-final { scan-assembler-times "memset" 3 { target elf } } } */
+/* { dg-final { scan-assembler-times "memset" 2 { target { ! elf } } } } */
char a[2048];
void t (void)
@@ -16,6 +16,7 @@ integer :: aa(4,4)
call test(aa)
end
-! { dg-final { scan-assembler-times "\[ \t\]\[$,_0-9\]*myBindC" 1 { target { ! { hppa*-*-* } } } } }
+! { dg-final { scan-assembler-times "\[ \t\]\[$,_0-9\]*myBindC" 1 { target { ! elf } && target { ! { hppa*-*-* } } } } }
+! { dg-final { scan-assembler-times "\[ \t\]\[$,_0-9\]*myBindC" 2 { target { elf && { ! { hppa*-*-* } } } } } }
! { dg-final { scan-assembler-times "myBindC,%r2" 1 { target { hppa*-*-* } } } }
! { dg-final { scan-tree-dump-times "test \\\(&parm\\." 1 "original" } }
@@ -6349,3 +6349,23 @@ proc check_effective_target_comdat_group {} {
int (*fn) () = foo;
}]
}
+
+# Returns 1 if the target is ELF.
+
+proc check_effective_target_elf { } {
+ global check_effective_target_elf_saved
+ global tool
+
+ if [info exists check_effective_target_elf_saved] {
+ verbose "check_effective_target_elf returning saved $check_effective_target_elf_saved" 2
+ } else {
+ set objformat [gcc_target_object_format]
+ if { $objformat == "elf" } {
+ set check_effective_target_elf_saved 1
+ } else {
+ set check_effective_target_elf_saved 0
+ }
+ verbose "check_effective_target_elf returning $check_effective_target_elf_saved" 2
+ }
+ return $check_effective_target_elf_saved
+}
@@ -7502,7 +7502,7 @@ elf_record_gcc_switches (print_switch_type type, const char * name)
}
/* Emit text to declare externally defined symbols. It is needed to
- properly support non-default visibility. */
+ properly support non-default visibility and specify symbol type. */
void
default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
tree decl,
@@ -7511,10 +7511,22 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
/* We output the name if and only if TREE_SYMBOL_REFERENCED is
set in order to avoid putting out names that are never really
used. Always output visibility specified in the source. */
- if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
- && (DECL_VISIBILITY_SPECIFIED (decl)
- || targetm.binds_local_p (decl)))
- maybe_assemble_visibility (decl);
+ if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
+ {
+ if (DECL_VISIBILITY_SPECIFIED (decl)
+ || targetm.binds_local_p (decl))
+ maybe_assemble_visibility (decl);
+
+#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
+ else if (TREE_CODE (decl) == VAR_DECL)
+ {
+ if (!DECL_THREAD_LOCAL_P (decl))
+ ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "object");
+ }
+#endif
+ }
}
/* The default hook for TARGET_ASM_OUTPUT_SOURCE_FILENAME. */
--
2.4.3