Bootstrapped and regtested 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 hook 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 <i...@linux.ibm.com> * asan.c (asan_emit_stack_protection): Provide an alignment hint. * config/s390/s390.c (TARGET_INSN_ALIGNMENT): Specify that s390 requires instructions to be aligned on a 2-byte boundary. * doc/tm.texi: Document TARGET_INSN_ALIGNMENT. * doc/tm.texi.in: Likewise. * target.def (insn_alignment): New hook. gcc/testsuite/ChangeLog: 2019-06-28 Ilya Leoshkevich <i...@linux.ibm.com> * gcc.target/s390/asan-no-gotoff.c: New test. --- gcc/asan.c | 1 + gcc/config/s390/s390.c | 3 +++ gcc/doc/tm.texi | 7 +++++++ gcc/doc/tm.texi.in | 2 ++ gcc/target.def | 9 +++++++++ gcc/testsuite/gcc.target/s390/asan-no-gotoff.c | 15 +++++++++++++++ 6 files changed, 37 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..c436f437375 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, targetm.insn_alignment); 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.c b/gcc/config/s390/s390.c index 5ec26a0592b..7ac2c8bdf76 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -16651,6 +16651,9 @@ s390_sched_dependencies_evaluation (rtx_insn *head, rtx_insn *tail) #undef TARGET_MAX_ANCHOR_OFFSET #define TARGET_MAX_ANCHOR_OFFSET 0xfff +#undef TARGET_INSN_ALIGNMENT +#define TARGET_INSN_ALIGNMENT 16 + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-s390.h" diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 14c1ea6a323..142c7c04c46 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1464,6 +1464,13 @@ appropriate for a target that does not define any new fundamental types. @end deftypefn +@deftypevr {Target Hook} HOST_WIDE_INT TARGET_INSN_ALIGNMENT +Certain architectures require individual machine instructions to +be aligned - e.g. on a 4-byte boundary on arm, mips and ppc, or +on a 2-byte boundary on s390. Define this to specify such +instruction alignment in bits. The default value is 8. +@end deftypevr + @node Type Layout @section Layout of Source Language Data Types diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index b4d57b86e2f..97578d6de27 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -1282,6 +1282,8 @@ pattern needs to support both a 32- and a 64-bit mode. @hook TARGET_MANGLE_TYPE +@hook TARGET_INSN_ALIGNMENT + @node Type Layout @section Layout of Source Language Data Types diff --git a/gcc/target.def b/gcc/target.def index 41654054ad8..1f6fac4b830 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -3185,6 +3185,15 @@ DEFHOOK bool, (struct ao_ref *ref), default_ref_may_alias_errno) +/* Machine instruction alignment. */ +DEFHOOKPOD +(insn_alignment, + "Certain architectures require individual machine instructions to\n\ +be aligned - e.g. on a 4-byte boundary on arm, mips and ppc, or\n\ +on a 2-byte boundary on s390. Define this to specify such\n\ +instruction alignment in bits. The default value is 8.", + HOST_WIDE_INT, 8) + /* Support for named address spaces. */ #undef HOOK_PREFIX #define HOOK_PREFIX "TARGET_ADDR_SPACE_" 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