[PATCH v2] S/390: Improve storing asan frame_pc

Ilya Leoshkevich iii@linux.ibm.com
Tue Jul 2 15:34:00 GMT 2019


Bootstrap and regtest running on x86_64-redhat-linux, s390x-redhat-linux
and ppc64le-redhat-linux.

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

diff --git a/gcc/asan.c b/gcc/asan.c
index 605d04f87f7..2db69f476bc 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1523,6 +1523,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 969f58a2ba0..3d0266c9dff 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -334,6 +334,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 af7ea185f1e..97c4c17537d 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1459,4 +1459,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define DWARF_GNAT_ENCODINGS_DEFAULT DWARF_GNAT_ENCODINGS_GDB
 #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 14c1ea6a323..3b50fc0c0a7 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1019,6 +1019,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 b4d57b86e2f..ab038b7462c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -969,6 +969,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} } } */
-- 
2.21.0



More information about the Gcc-patches mailing list