From a2e0a30c52faa022421f5d2cc55abc487c86ab01 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich <iii@linux.ibm.com> Date: Thu, 13 Oct 2022 02:54:52 +0200 Subject: [PATCH] IBM zSystems: Do not use @PLT with larl Commit 0990d93dd8a4 ("IBM Z: Use @PLT symbols for local functions in 64-bit mode") made GCC call both static and non-static functions and load both static and non-static function addresses with the @PLT suffix. This made it difficult for linkers to distinguish calling and address taking instructions [1]. It is currently assumed that the R_390_PLT32DBL relocation, corresponding to the @PLT suffix, is used only for calling, and the R_390_PC32DBL relocation, corresponding to the empty suffix, is used only for address taking. Linkers needs to make this distinction in order to decide whether to ask ld.so to use canonical PLT entries. Normally GOT entries in shared objects contain addresses of the respective functions, with one notable exception: when a no-pie executable calls the respective function and also takes its address. Such executables assume that all addresses are known in advance, so they use addresses of the respective PLT entries. For consistency reasons, all respective GOT entries in the process must also use them. When a linker sees that a no-pie executable both calls a function and also takes its address, it creates a PLT entry and asks ld.so to consider it canonical by setting the respective undefined symbol's address, which is normally 0, to the address of this PLT entry. Improve the situation by not using @PLT with larl. Now that @PLT is not used with larl, also drop the 31-bit handling, which was required because 31-bit PLT entries require %r12 to point to the respective object's GOT, and this requirement is not satisfied when calling them by pointer from another object. Also drop the weak symbol handling, which was required because it is not possible to load an undefined weak symbol address (0) using larl. [1] https://sourceware.org/bugzilla/show_bug.cgi?id=29655 gcc/ChangeLog: * config/s390/s390.cc (print_operand): Remove the no longer necessary 31-bit and weak symbol handling. * config/s390/s390.md (*movdi_64): Do not use @PLT with larl. (*movsi_larl): Likewise. (main_base_64): Likewise. (reload_base_64): Likewise. gcc/testsuite/ChangeLog: * gcc.target/s390/call-z10-pic-nodatarel.c: Adjust expectations. * gcc.target/s390/call-z10-pic.c: Likewise. * gcc.target/s390/call-z10.c: Likewise. * gcc.target/s390/call-z9-pic-nodatarel.c: Likewise. * gcc.target/s390/call-z9-pic.c: Likewise. * gcc.target/s390/call-z9.c: Likewise. --- gcc/config/s390/s390.cc | 16 +++------------- gcc/config/s390/s390.md | 8 ++++---- .../gcc.target/s390/call-z10-pic-nodatarel.c | 6 ++---- gcc/testsuite/gcc.target/s390/call-z10-pic.c | 6 ++---- gcc/testsuite/gcc.target/s390/call-z10.c | 14 +++++--------- .../gcc.target/s390/call-z9-pic-nodatarel.c | 6 ++---- gcc/testsuite/gcc.target/s390/call-z9-pic.c | 6 ++---- gcc/testsuite/gcc.target/s390/call-z9.c | 14 +++++--------- 8 files changed, 25 insertions(+), 51 deletions(-) diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 86a5f059b85d..1d96df49feac 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -8585,7 +8585,7 @@ print_operand_address (FILE *file, rtx addr) 'E': print opcode suffix for branch on index instruction. 'G': print the size of the operand in bytes. 'J': print tls_load/tls_gdcall/tls_ldcall suffix - 'K': print @PLT suffix for call targets and load address values. + 'K': print @PLT suffix for branch targets; do not use with larl. 'M': print the second word of a TImode operand. 'N': print the second word of a DImode operand. 'O': print only the displacement of a memory reference or address. @@ -8854,19 +8854,9 @@ print_operand (FILE *file, rtx x, int code) call even static functions via PLT. ld will optimize @PLT away for normal code, and keep it for patches. - Do not indiscriminately add @PLT in 31-bit mode due to the %r12 - restriction, use UNSPEC_PLT31 instead. - @PLT only makes sense for functions, data is taken care of by - -mno-pic-data-is-text-relative. - - Adding @PLT interferes with handling of weak symbols in non-PIC code, - since their addresses are loaded with larl, which then always produces - a non-NULL result, so skip them here as well. */ - if (TARGET_64BIT - && GET_CODE (x) == SYMBOL_REF - && SYMBOL_REF_FUNCTION_P (x) - && !(SYMBOL_REF_WEAK (x) && !flag_pic)) + -mno-pic-data-is-text-relative. */ + if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x)) fprintf (file, "@PLT"); return; } diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index c164ea72c78b..9d4958033873 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -2001,7 +2001,7 @@ vlgvg\t%0,%v1,0 vleg\t%v0,%1,0 vsteg\t%v1,%0,0 - larl\t%0,%1%K1" + larl\t%0,%1" [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RRE,RXY,RIL,RRE,RXY, RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS, VRX,VRX,RIL") @@ -2390,7 +2390,7 @@ (match_operand:SI 1 "larl_operand" "X"))] "!TARGET_64BIT && !FP_REG_P (operands[0])" - "larl\t%0,%1%K1" + "larl\t%0,%1" [(set_attr "op_type" "RIL") (set_attr "type" "larl") (set_attr "z10prop" "z10_fwd_A1") @@ -11735,7 +11735,7 @@ [(set (match_operand 0 "register_operand" "=a") (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))] "GET_MODE (operands[0]) == Pmode" - "larl\t%0,%1%K1" + "larl\t%0,%1" [(set_attr "op_type" "RIL") (set_attr "type" "larl") (set_attr "z10prop" "z10_fwd_A1") @@ -11755,7 +11755,7 @@ [(set (match_operand 0 "register_operand" "=a") (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))] "GET_MODE (operands[0]) == Pmode" - "larl\t%0,%1%K1" + "larl\t%0,%1" [(set_attr "op_type" "RIL") (set_attr "type" "larl") (set_attr "z10prop" "z10_fwd_A1")]) diff --git a/gcc/testsuite/gcc.target/s390/call-z10-pic-nodatarel.c b/gcc/testsuite/gcc.target/s390/call-z10-pic-nodatarel.c index 49984614bc6f..6df0c75584f4 100644 --- a/gcc/testsuite/gcc.target/s390/call-z10-pic-nodatarel.c +++ b/gcc/testsuite/gcc.target/s390/call-z10-pic-nodatarel.c @@ -7,10 +7,8 @@ /* { dg-final { scan-assembler {lgrl\t%r2,foo@GOTENT\n} { target lp64 } } } */ /* { dg-final { scan-assembler {lrl\t%r2,foo@GOTENT\n} { target { ! lp64 } } } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic\n} { target { ! lp64 } } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} } } */ +/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} } } */ /* { dg-final { scan-assembler {brasl\t%r\d+,fooweak@PLT\n} } } */ /* { dg-final { scan-assembler {lgrl\t%r2,fooweak@GOTENT\n} { target lp64 } } } */ diff --git a/gcc/testsuite/gcc.target/s390/call-z10-pic.c b/gcc/testsuite/gcc.target/s390/call-z10-pic.c index 210c56cc4cad..30145d5b7608 100644 --- a/gcc/testsuite/gcc.target/s390/call-z10-pic.c +++ b/gcc/testsuite/gcc.target/s390/call-z10-pic.c @@ -7,10 +7,8 @@ /* { dg-final { scan-assembler {lgrl\t%r2,foo@GOTENT\n} { target lp64 } } } */ /* { dg-final { scan-assembler {lrl\t%r2,foo@GOTENT\n} { target { ! lp64 } } } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic\n} { target { ! lp64 } } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} } } */ +/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} } } */ /* { dg-final { scan-assembler {brasl\t%r\d+,fooweak@PLT\n} } } */ /* { dg-final { scan-assembler {lgrl\t%r2,fooweak@GOTENT\n} { target lp64 } } } */ diff --git a/gcc/testsuite/gcc.target/s390/call-z10.c b/gcc/testsuite/gcc.target/s390/call-z10.c index 2d7dc735df4a..d4eab4ff89fc 100644 --- a/gcc/testsuite/gcc.target/s390/call-z10.c +++ b/gcc/testsuite/gcc.target/s390/call-z10.c @@ -3,17 +3,13 @@ #include "call.h" -/* { dg-final { scan-assembler {brasl\t%r\d+,foo@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foo\n} { target { ! lp64 } } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foo@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foo\n} { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler {brasl\t%r\d+,foo@PLT\n} } } */ +/* { dg-final { scan-assembler {larl\t%r2,foo\n} } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic\n} { target { ! lp64 } } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} } } */ +/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,fooweak\n} } } */ +/* { dg-final { scan-assembler {brasl\t%r\d+,fooweak@PLT\n} } } */ /* { dg-final { scan-assembler {larl\t%r2,fooweak\n} } } */ /* { dg-final { scan-assembler {foos:\n\t.quad\tfoo\n\t.quad\tfoostatic\n\t.quad\tfooweak\n} { target lp64 } } } */ diff --git a/gcc/testsuite/gcc.target/s390/call-z9-pic-nodatarel.c b/gcc/testsuite/gcc.target/s390/call-z9-pic-nodatarel.c index b1ae318d3e99..fe515bf1903d 100644 --- a/gcc/testsuite/gcc.target/s390/call-z9-pic-nodatarel.c +++ b/gcc/testsuite/gcc.target/s390/call-z9-pic-nodatarel.c @@ -6,10 +6,8 @@ /* { dg-final { scan-assembler {brasl\t%r\d+,foo@PLT\n} } } */ /* { dg-final { scan-assembler {larl\t%r\d+,foo@GOTENT\n} } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic\n} { target { ! lp64 } } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} } } */ +/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} } } */ /* { dg-final { scan-assembler {brasl\t%r\d+,fooweak@PLT\n} } } */ /* { dg-final { scan-assembler {larl\t%r\d+,fooweak@GOTENT\n} } } */ diff --git a/gcc/testsuite/gcc.target/s390/call-z9-pic.c b/gcc/testsuite/gcc.target/s390/call-z9-pic.c index a89e78d8df8e..43e1c2f7cb38 100644 --- a/gcc/testsuite/gcc.target/s390/call-z9-pic.c +++ b/gcc/testsuite/gcc.target/s390/call-z9-pic.c @@ -6,10 +6,8 @@ /* { dg-final { scan-assembler {brasl\t%r\d+,foo@PLT\n} } } */ /* { dg-final { scan-assembler {larl\t%r\d+,foo@GOTENT\n} } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic\n} { target { ! lp64 } } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} } } */ +/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} } } */ /* { dg-final { scan-assembler {brasl\t%r\d+,fooweak@PLT\n} } } */ /* { dg-final { scan-assembler {larl\t%r\d+,fooweak@GOTENT\n} } } */ diff --git a/gcc/testsuite/gcc.target/s390/call-z9.c b/gcc/testsuite/gcc.target/s390/call-z9.c index 21d035aecb6b..b755f33498a3 100644 --- a/gcc/testsuite/gcc.target/s390/call-z9.c +++ b/gcc/testsuite/gcc.target/s390/call-z9.c @@ -3,17 +3,13 @@ #include "call.h" -/* { dg-final { scan-assembler {brasl\t%r\d+,foo@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foo\n} { target { ! lp64 } } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foo@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foo\n} { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler {brasl\t%r\d+,foo@PLT\n} } } */ +/* { dg-final { scan-assembler {larl\t%r2,foo\n} } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic\n} { target { ! lp64 } } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic@PLT\n} { target lp64 } } } */ -/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler {brasl\t%r\d+,foostatic@PLT\n} } } */ +/* { dg-final { scan-assembler {larl\t%r2,foostatic\n} } } */ -/* { dg-final { scan-assembler {brasl\t%r\d+,fooweak\n} } } */ +/* { dg-final { scan-assembler {brasl\t%r\d+,fooweak@PLT\n} } } */ /* { dg-final { scan-assembler {larl\t%r2,fooweak\n} } } */ /* { dg-final { scan-assembler {foos:\n\t.quad\tfoo\n\t.quad\tfoostatic\n\t.quad\tfooweak\n} { target lp64 } } } */ -- GitLab