S/390: New option -mpic-data-is-text-relative
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Wed, 28 Jun 2017 07:03:35 +0000 (07:03 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Wed, 28 Jun 2017 07:03:35 +0000 (07:03 +0000)
For hotpatching it might be required to introduce new .text parts
while keep using the existing .data/.bss sections.  To make this work
the backend needs to be prevented from using relative addressing
between code and data.
This only works when already building PIC
since the addressing will then be handling via GOT.

gcc/testsuite/ChangeLog:

2017-06-28  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

* gcc.target/s390/nodatarel-1.c: New test.

gcc/ChangeLog:

2017-06-28  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

* config/s390/predicates.md: Use s390_rel_address_ok_p.
* config/s390/s390-protos.h: Add prototype of
s390_rel_address_ok_p.
* config/s390/s390.c (s390_got_symbol): New function.
(s390_rel_address_ok_p): New function.
(legitimize_pic_address): Use s390_rel_address_ok_p.
(s390_load_got): Use s390_got_symbol.
(s390_option_override): Issue error if
-mno-pic-data-is-text-relative is used without -fpic/-fPIC.
* config/s390/s390.h (TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE):
New macro.
* config/s390/s390.opt: New option mpic-data-is-text-relative.

From-SVN: r249720

gcc/ChangeLog
gcc/config/s390/predicates.md
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/s390/s390.opt
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/nodatarel-1.c [new file with mode: 0644]

index f52d1b92a236af0f32c552b2407e4c03e1b9b825..48c81b3a9c2317fc2973666e8064a7b5b6785d90 100644 (file)
@@ -1,3 +1,18 @@
+2017-06-28  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
+
+       * config/s390/predicates.md: Use s390_rel_address_ok_p.
+       * config/s390/s390-protos.h: Add prototype of
+       s390_rel_address_ok_p.
+       * config/s390/s390.c (s390_got_symbol): New function.
+       (s390_rel_address_ok_p): New function.
+       (legitimize_pic_address): Use s390_rel_address_ok_p.
+       (s390_load_got): Use s390_got_symbol.
+       (s390_option_override): Issue error if
+       -mno-pic-data-is-text-relative is used without -fpic/-fPIC.
+       * config/s390/s390.h (TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE):
+       New macro.
+       * config/s390/s390.opt: New option mpic-data-is-text-relative.
+
 2017-06-27  Andrew Pinski  <apinski@cavium.com>
 
        * match.pd (X >/>=/</<= 0 ? 1.0 : -1.0): New patterns.
index 34a7ea284556618093501a8f9613ee0feb4215e3..fc151ac1d2800e240f604851fe0d8b690a0124c4 100644 (file)
   /* Allow labels and local symbols.  */
   if (GET_CODE (op) == LABEL_REF)
     return true;
-  if (GET_CODE (op) == SYMBOL_REF)
+  if (SYMBOL_REF_P (op))
     return (!SYMBOL_FLAG_NOTALIGN2_P (op)
            && SYMBOL_REF_TLS_MODEL (op) == 0
-           && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
+           && s390_rel_address_ok_p (op));
 
   /* Everything else must have a CONST, so strip it.  */
   if (GET_CODE (op) != CONST)
   /* Labels and local symbols allowed here as well.  */
   if (GET_CODE (op) == LABEL_REF)
     return true;
-  if (GET_CODE (op) == SYMBOL_REF)
+  if (SYMBOL_REF_P (op))
     return (!SYMBOL_FLAG_NOTALIGN2_P (op)
            && SYMBOL_REF_TLS_MODEL (op) == 0
-           && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
+           && s390_rel_address_ok_p (op));
+
 
   /* Now we must have a @GOTENT offset or @PLT stub
      or an @INDNTPOFF TLS offset.  */
index 3fdb32059cd91c36520c42fb10955fef3615a99b..6df37ef9bf7b385987c153917c1a5e35b712f189 100644 (file)
@@ -79,6 +79,7 @@ extern bool s390_bytemask_vector_p (rtx, unsigned *);
 extern bool s390_split_ok_p (rtx, rtx, machine_mode, int);
 extern bool s390_overlap_p (rtx, rtx, HOST_WIDE_INT);
 extern bool s390_offset_p (rtx, rtx, rtx);
+extern bool s390_rel_address_ok_p (rtx);
 extern int tls_symbolic_operand (rtx);
 
 extern bool s390_match_ccmode (rtx_insn *, machine_mode);
index eb94237d96992ccc0f65678e22e09d551589b023..bfc38db58f4ec812906bf1e719a074ef26db0fca 100644 (file)
@@ -1179,6 +1179,23 @@ s390_label_align (rtx_insn *label)
   return align_labels_log;
 }
 
+static GTY(()) rtx got_symbol;
+
+/* Return the GOT table symbol.  The symbol will be created when the
+   function is invoked for the first time.  */
+
+static rtx
+s390_got_symbol (void)
+{
+  if (!got_symbol)
+    {
+      got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+      SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
+    }
+
+  return got_symbol;
+}
+
 static machine_mode
 s390_libgcc_cmp_return_mode (void)
 {
@@ -4496,6 +4513,26 @@ s390_load_address (rtx dst, rtx src)
     emit_insn (gen_force_la_31 (dst, src));
 }
 
+/* Return true if it ok to use SYMBOL_REF in a relative address.  */
+
+bool
+s390_rel_address_ok_p (rtx symbol_ref)
+{
+  tree decl;
+
+  if (symbol_ref == s390_got_symbol () || CONSTANT_POOL_ADDRESS_P (symbol_ref))
+    return true;
+
+  decl = SYMBOL_REF_DECL (symbol_ref);
+
+  if (!flag_pic || SYMBOL_REF_LOCAL_P (symbol_ref))
+    return (s390_pic_data_is_text_relative
+           || (decl
+               && TREE_CODE (decl) == FUNCTION_DECL));
+
+  return false;
+}
+
 /* Return a legitimate reference for ORIG (an address) using the
    register REG.  If REG is 0, a new pseudo is generated.
 
@@ -4533,7 +4570,7 @@ legitimize_pic_address (rtx orig, rtx reg)
     }
 
   if ((GET_CODE (addr) == LABEL_REF
-       || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr))
+       || (SYMBOL_REF_P (addr) && s390_rel_address_ok_p (addr))
        || (GET_CODE (addr) == UNSPEC &&
           (XINT (addr, 1) == UNSPEC_GOTENT
            || (TARGET_CPU_ZARCH && XINT (addr, 1) == UNSPEC_PLT))))
@@ -10791,7 +10828,6 @@ restore_gprs (rtx base, int offset, int first, int last)
 
 /* Return insn sequence to load the GOT register.  */
 
-static GTY(()) rtx got_symbol;
 rtx_insn *
 s390_load_got (void)
 {
@@ -10803,23 +10839,17 @@ s390_load_got (void)
      aren't usable.  */
   rtx got_rtx = gen_rtx_REG (Pmode, 12);
 
-  if (!got_symbol)
-    {
-      got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
-      SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
-    }
-
   start_sequence ();
 
   if (TARGET_CPU_ZARCH)
     {
-      emit_move_insn (got_rtx, got_symbol);
+      emit_move_insn (got_rtx, s390_got_symbol ());
     }
   else
     {
       rtx offset;
 
-      offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
+      offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, s390_got_symbol ()),
                               UNSPEC_LTREL_OFFSET);
       offset = gen_rtx_CONST (Pmode, offset);
       offset = force_const_mem (Pmode, offset);
@@ -14911,6 +14941,9 @@ s390_option_override (void)
   if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch && optimize >= 3)
     flag_prefetch_loop_arrays = 1;
 
+  if (!s390_pic_data_is_text_relative && !flag_pic)
+    error ("-mno-pic-data-is-text-relative cannot be used without -fpic/-fPIC");
+
   if (TARGET_TPF)
     {
       /* Don't emit DWARF3/4 unless specifically selected.  The TPF
index a372981ff3a4e6e306a8f0d8f74a88e3d730d5e2..7847047d160d6b7df6c69b8bdf3bd4dd55e0c0ab 100644 (file)
@@ -946,6 +946,10 @@ CUMULATIVE_ARGS;
 
 #define LEGITIMATE_PIC_OPERAND_P(X)  legitimate_pic_operand_p (X)
 
+#ifndef TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE
+#define TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE 1
+#endif
+
 
 /* Assembler file format.  */
 
index d0a0d46b0a736b5b1950a6fc682bfa554425e5b6..f277ac55effac293578f83058807ed8e4e1a1521 100644 (file)
@@ -226,3 +226,7 @@ values are small, non-negative integers.  The default branch cost is
 mlra
 Target Report Var(s390_lra_flag) Init(1) Save
 Use LRA instead of reload.
+
+mpic-data-is-text-relative
+Target Report Var(s390_pic_data_is_text_relative) Init(TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE)
+Assume data segments are relative to text segment.
index 46879b7998d67181cd809944c8ef02d16f51b289..4ed5542d4954287e808d30e7bcb5af83b75c0250 100644 (file)
@@ -1,3 +1,7 @@
+2017-06-28  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
+
+       * gcc.target/s390/nodatarel-1.c: New test.
+
 2017-06-27  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/80164
diff --git a/gcc/testsuite/gcc.target/s390/nodatarel-1.c b/gcc/testsuite/gcc.target/s390/nodatarel-1.c
new file mode 100644 (file)
index 0000000..1d589a1
--- /dev/null
@@ -0,0 +1,83 @@
+/* Test -mno-pic-data-is-text-relative option.  No relative addressing
+   of elements in .data and .bss are allowed with that option.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-optimize-sibling-calls -fpic -mno-pic-data-is-text-relative -march=z10 -mtune=z9-109 -mzarch" } */
+
+static int a = 3;
+
+/* With -mno-pic-data-is-text-relative these must be addressed via
+   GOT.  */
+
+int __attribute__((noinline,noclone))
+foo ()
+{
+  return a;
+}
+
+static int __attribute__((noinline,noclone))
+foostatic (void)
+{
+  return a;
+}
+
+/* Just to make a potentially modified.  */
+
+void
+bar (int b)
+{
+  a = b;
+}
+
+/* { dg-final { scan-assembler-times "a@GOTENT" 3 } } */
+
+/* The exrl target is a label_ref which should not be affected at
+   all.  */
+
+void
+mymemcpy (char *dst, char *src, long size)
+{
+  __builtin_memcpy (dst, src, size);
+}
+
+/* { dg-final { scan-assembler "exrl" } } */
+
+
+/* PLT slots can still be addressed relatively.  */
+
+int
+callfoo ()
+{
+  return foo ();
+}
+
+/* { dg-final { scan-assembler-times "foo@PLT" 1 } } */
+
+
+/* GOT entries can still be addressed relatively.  */
+
+void *
+fooptr ()
+{
+  return &foo;
+}
+
+/* { dg-final { scan-assembler-times "foo@GOTENT" 1 } } */
+
+
+/* A static function can be addressed relatively.  */
+
+int
+callfoostatic ()
+{
+  return foostatic ();
+}
+
+void *
+foostaticptr ()
+{
+  return &foostatic;
+}
+
+
+/* { dg-final { scan-assembler-not "foostatic@" } } */