[v3] S/390: Improve storing asan frame_pc

Message ID 20200617102036.659552-1-iii@linux.ibm.com
State New
Headers show
Series
  • [v3] S/390: Improve storing asan frame_pc
Related show

Commit Message

Jakub Jelinek via Gcc-patches June 17, 2020, 10:20 a.m.
Hello,

This is a resend of v2 (rebased on the latest master).

Previous discussions:

v1: https://gcc.gnu.org/pipermail/gcc-patches/2019-July/525016.html
v2: https://gcc.gnu.org/pipermail/gcc-patches/2019-July/525069.html

Is there anything I need to change (e.g. in the naming area) to get this
change accepted?

Best regards,
Ilya

---

Currently s390 emits the following sequence to store a frame_pc:

        a:
        .LASANPC0:

                lg      %r1,.L5-.L4(%r13)
                la      %r1,0(%r1,%r12)
                stg     %r1,176(%r11)

        .L5:
                .quad   .LASANPC0@GOTOFF

The reason GOT indirection is used instead of larl is that gcc does not
know that .LASANPC0, being a code label, is aligned on a 2-byte
boundary, and larl can load only even addresses.

This patch provides such an alignment hint.  Since targets don't provide
their instruction alignments yet, the new macro is introduced for that
purpose.  It returns 1-byte alignment by default, so this change is a
no-op for targets other than s390.

As a result, we get the desired:

                larl    %r1,.LASANPC0
                stg     %r1,176(%r11)

gcc/ChangeLog:

2019-06-28  Ilya Leoshkevich  <iii@linux.ibm.com>

        * asan.c (asan_emit_stack_protection): Provide an alignment
        hint.
        * config/s390/s390.h (CODE_LABEL_BOUNDARY): Specify that s390
        requires code labels to be aligned on a 2-byte boundary.
        * defaults.h (CODE_LABEL_BOUNDARY): New macro.
        * doc/tm.texi: Document CODE_LABEL_BOUNDARY.
        * doc/tm.texi.in: Likewise.

gcc/testsuite/ChangeLog:

2019-06-28  Ilya Leoshkevich  <iii@linux.ibm.com>

        * gcc.target/s390/asan-no-gotoff.c: New test.
---
 gcc/asan.c                                     |  1 +
 gcc/config/s390/s390.h                         |  3 +++
 gcc/defaults.h                                 |  5 +++++
 gcc/doc/tm.texi                                |  4 ++++
 gcc/doc/tm.texi.in                             |  4 ++++
 gcc/testsuite/gcc.target/s390/asan-no-gotoff.c | 15 +++++++++++++++
 6 files changed, 32 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/s390/asan-no-gotoff.c

-- 
2.25.4

Patch

diff --git a/gcc/asan.c b/gcc/asan.c
index 9c9aa4cae35..cc06afb9ddc 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1524,6 +1524,7 @@  asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
   DECL_INITIAL (decl) = decl;
   TREE_ASM_WRITTEN (decl) = 1;
   TREE_ASM_WRITTEN (id) = 1;
+  SET_DECL_ALIGN (decl, CODE_LABEL_BOUNDARY);
   emit_move_insn (mem, expand_normal (build_fold_addr_expr (decl)));
   shadow_base = expand_binop (Pmode, lshr_optab, base,
 			      gen_int_shift_amount (Pmode, ASAN_SHADOW_SHIFT),
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index e4ef63e4080..08ce500ab00 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -343,6 +343,9 @@  extern const char *s390_host_detect_local_cpu (int argc, const char **argv);
 /* Allocation boundary (in *bits*) for the code of a function.  */
 #define FUNCTION_BOUNDARY 64
 
+/* Alignment required for a code label, in bits.  */
+#define CODE_LABEL_BOUNDARY 16
+
 /* There is no point aligning anything to a rounder boundary than this.  */
 #define BIGGEST_ALIGNMENT 64
 
diff --git a/gcc/defaults.h b/gcc/defaults.h
index f1a38626624..e5a9139bbbe 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1473,4 +1473,9 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 typedef TARGET_UNIT target_unit;
 #endif
 
+/* Alignment required for a code label, in bits.  */
+#ifndef CODE_LABEL_BOUNDARY
+#define CODE_LABEL_BOUNDARY BITS_PER_UNIT
+#endif
+
 #endif  /* ! GCC_DEFAULTS_H */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 6e7d9dc54a9..16e48ce59d8 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1011,6 +1011,10 @@  to a value equal to or larger than @code{STACK_BOUNDARY}.
 Alignment required for a function entry point, in bits.
 @end defmac
 
+@defmac CODE_LABEL_BOUNDARY
+Alignment required for a code label, in bits.
+@end defmac
+
 @defmac BIGGEST_ALIGNMENT
 Biggest alignment that any data type can require on this machine, in
 bits.  Note that this is not the biggest alignment that is supported,
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 3be984bbd5c..12f8c05f5dd 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -965,6 +965,10 @@  to a value equal to or larger than @code{STACK_BOUNDARY}.
 Alignment required for a function entry point, in bits.
 @end defmac
 
+@defmac CODE_LABEL_BOUNDARY
+Alignment required for a code label, in bits.
+@end defmac
+
 @defmac BIGGEST_ALIGNMENT
 Biggest alignment that any data type can require on this machine, in
 bits.  Note that this is not the biggest alignment that is supported,
diff --git a/gcc/testsuite/gcc.target/s390/asan-no-gotoff.c b/gcc/testsuite/gcc.target/s390/asan-no-gotoff.c
new file mode 100644
index 00000000000..f555e4e96f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/asan-no-gotoff.c
@@ -0,0 +1,15 @@ 
+/* Test that ASAN labels are referenced without unnecessary indirections.  */
+
+/* { dg-do compile } */
+/* { dg-options "-fPIE -O2 -fsanitize=kernel-address --param asan-stack=1" } */
+
+extern void c (int *);
+
+void a ()
+{
+  int b;
+  c (&b);
+}
+
+/* { dg-final { scan-assembler {\tlarl\t%r\d+,\.LASANPC\d+} } } */
+/* { dg-final { scan-assembler-not {\.LASANPC\d+@GOTOFF} } } */