diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2017-06-28 07:03:35 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel@gcc.gnu.org> | 2017-06-28 07:03:35 +0000 |
commit | 935b5226c385e34088c314374cbbe9e4995b9e44 (patch) | |
tree | 23d3790403d00862b7e13222615a0f27eeb982cc /gcc | |
parent | 8801653208ef13e4762d907971e3a6b83a8e721e (diff) | |
download | gcc-935b5226c385e34088c314374cbbe9e4995b9e44.zip gcc-935b5226c385e34088c314374cbbe9e4995b9e44.tar.gz gcc-935b5226c385e34088c314374cbbe9e4995b9e44.tar.bz2 |
S/390: New option -mpic-data-is-text-relative
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/config/s390/predicates.md | 9 | ||||
-rw-r--r-- | gcc/config/s390/s390-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 53 | ||||
-rw-r--r-- | gcc/config/s390/s390.h | 4 | ||||
-rw-r--r-- | gcc/config/s390/s390.opt | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/nodatarel-1.c | 83 |
8 files changed, 159 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f52d1b9..48c81b3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md index 34a7ea2..fc151ac 100644 --- a/gcc/config/s390/predicates.md +++ b/gcc/config/s390/predicates.md @@ -131,10 +131,10 @@ /* 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) @@ -156,10 +156,11 @@ /* 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. */ diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 3fdb320..6df37ef 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -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); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index eb94237..bfc38db 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -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 diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index a372981..7847047 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -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. */ diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt index d0a0d46..f277ac5 100644 --- a/gcc/config/s390/s390.opt +++ b/gcc/config/s390/s390.opt @@ -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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 46879b7..4ed5542 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..1d589a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/nodatarel-1.c @@ -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@" } } */ |