186 lines
7.1 KiB
Diff
186 lines
7.1 KiB
Diff
|
From cea6ee90a846468f87f71a592c9761a5136646b7 Mon Sep 17 00:00:00 2001
|
||
|
From: Jakub Jelinek <jakub@redhat.com>
|
||
|
Date: Sat, 3 Apr 2021 10:03:15 +0200
|
||
|
Subject: [PATCH 22/23] Backport rs6000: Avoid -fpatchable-function-entry*
|
||
|
regressions on powerpc64 be [PR98125]
|
||
|
|
||
|
The SECTION_LINK_ORDER changes broke powerpc64-linux ELFv1. Seems
|
||
|
that the assembler/linker relies on the symbol mentioned for the
|
||
|
"awo" section to be in the same section as the symbols mentioned in
|
||
|
the relocations in that section (i.e. labels for the patchable area
|
||
|
in this case). That is the case for most targets, including powerpc-linux
|
||
|
32-bit or powerpc64 ELFv2 (that one has -fpatchable-function-entry*
|
||
|
support broken for other reasons and it doesn't seem to be a regression).
|
||
|
But it doesn't work on powerpc64-linux ELFv1.
|
||
|
We emit:
|
||
|
.section ".opd","aw"
|
||
|
.align 3
|
||
|
_Z3foov:
|
||
|
.quad .L._Z3foov,.TOC.@tocbase,0
|
||
|
.previous
|
||
|
.type _Z3foov, @function
|
||
|
.L._Z3foov:
|
||
|
.section __patchable_function_entries,"awo",@progbits,_Z3foov
|
||
|
.align 3
|
||
|
.8byte .LPFE1
|
||
|
.section .text._Z3foov,"axG",@progbits,_Z3foov,comdat
|
||
|
.LPFE1:
|
||
|
nop
|
||
|
.LFB0:
|
||
|
.cfi_startproc
|
||
|
and because _Z3foov is in the .opd section rather than the function text
|
||
|
section, it doesn't work.
|
||
|
|
||
|
I'm afraid I don't know what exactly should be done, whether e.g.
|
||
|
it could use
|
||
|
.section __patchable_function_entries,"awo",@progbits,.L._Z3foov
|
||
|
instead, or whether the linker should be changed to handle it as is, or
|
||
|
something else.
|
||
|
|
||
|
But because we have a P1 regression that didn't see useful progress over the
|
||
|
4 months since it has been filed and we don't really have much time, below
|
||
|
is an attempt to do a targetted reversion of H.J's patch, basically act as
|
||
|
if HAVE_GAS_SECTION_LINK_ORDER is never true for powerpc64-linux ELFv1,
|
||
|
but for 32-bit or 64-bit ELFv2 keep working as is.
|
||
|
This would give us time to resolve it for GCC 12 properly.
|
||
|
|
||
|
2021-04-03 Jakub Jelinek <jakub@redhat.com>
|
||
|
|
||
|
PR testsuite/98125
|
||
|
* targhooks.h (default_print_patchable_function_entry_1): Declare.
|
||
|
* targhooks.c (default_print_patchable_function_entry_1): New function,
|
||
|
copied from default_print_patchable_function_entry with an added flags
|
||
|
argument.
|
||
|
(default_print_patchable_function_entry): Rewritten into a small
|
||
|
wrapper around default_print_patchable_function_entry_1.
|
||
|
* config/rs6000/rs6000.c (TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY):
|
||
|
Redefine.
|
||
|
(rs6000_print_patchable_function_entry): New function.
|
||
|
|
||
|
* g++.dg/pr93195a.C: Skip on powerpc*-*-* 64-bit.
|
||
|
---
|
||
|
gcc/config/rs6000/rs6000.c | 8 +++++--
|
||
|
gcc/targhooks.c | 38 ++++++++++++++++++++++-----------
|
||
|
gcc/targhooks.h | 3 +++
|
||
|
gcc/testsuite/g++.dg/pr93195a.C | 1 +
|
||
|
4 files changed, 36 insertions(+), 14 deletions(-)
|
||
|
|
||
|
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
|
||
|
index af0c7ce1656..ac60d6d39ac 100644
|
||
|
--- a/gcc/config/rs6000/rs6000.c
|
||
|
+++ b/gcc/config/rs6000/rs6000.c
|
||
|
@@ -1615,6 +1615,10 @@ static const struct attribute_spec rs6000_attribute_table[] =
|
||
|
#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
|
||
|
#endif
|
||
|
|
||
|
+#undef TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY
|
||
|
+#define TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY \
|
||
|
+ rs6000_print_patchable_function_entry
|
||
|
+
|
||
|
#undef TARGET_SET_UP_BY_PROLOGUE
|
||
|
#define TARGET_SET_UP_BY_PROLOGUE rs6000_set_up_by_prologue
|
||
|
|
||
|
@@ -27933,8 +27937,8 @@ debug_stack_info (rs6000_stack_t *info)
|
||
|
fprintf (stderr, "\n");
|
||
|
}
|
||
|
|
||
|
-rtx
|
||
|
-rs6000_return_addr (int count, rtx frame)
|
||
|
+enum rtx_code
|
||
|
+rs6000_reverse_condition (machine_mode mode, enum rtx_code code)
|
||
|
{
|
||
|
/* We can't use get_hard_reg_initial_val for LR when count == 0 if LR
|
||
|
is trashed by the prologue, as it is for PIC on ABI_V4 and Darwin. */
|
||
|
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
|
||
|
index 8aa610f5cde..958ec4ba6ff 100644
|
||
|
--- a/gcc/targhooks.c
|
||
|
+++ b/gcc/targhooks.c
|
||
|
@@ -1610,17 +1610,15 @@ default_compare_by_pieces_branch_ratio (machine_mode)
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
-/* Write PATCH_AREA_SIZE NOPs into the asm outfile FILE around a function
|
||
|
- entry. If RECORD_P is true and the target supports named sections,
|
||
|
- the location of the NOPs will be recorded in a special object section
|
||
|
- called "__patchable_function_entries". This routine may be called
|
||
|
- twice per function to put NOPs before and after the function
|
||
|
- entry. */
|
||
|
+/* Helper for default_print_patchable_function_entry and other
|
||
|
+ print_patchable_function_entry hook implementations. */
|
||
|
|
||
|
void
|
||
|
-default_print_patchable_function_entry (FILE *file,
|
||
|
- unsigned HOST_WIDE_INT patch_area_size,
|
||
|
- bool record_p)
|
||
|
+default_print_patchable_function_entry_1 (FILE *file,
|
||
|
+ unsigned HOST_WIDE_INT
|
||
|
+ patch_area_size,
|
||
|
+ bool record_p,
|
||
|
+ unsigned int flags)
|
||
|
{
|
||
|
const char *nop_templ = 0;
|
||
|
int code_num;
|
||
|
@@ -1642,9 +1640,6 @@ default_print_patchable_function_entry (FILE *file,
|
||
|
patch_area_number++;
|
||
|
ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", patch_area_number);
|
||
|
|
||
|
- unsigned int flags = SECTION_WRITE | SECTION_RELRO;
|
||
|
- if (HAVE_GAS_SECTION_LINK_ORDER)
|
||
|
- flags |= SECTION_LINK_ORDER;
|
||
|
switch_to_section (get_section ("__patchable_function_entries",
|
||
|
flags, current_function_decl));
|
||
|
assemble_align (POINTER_SIZE);
|
||
|
@@ -1661,6 +1656,25 @@ default_print_patchable_function_entry (FILE *file,
|
||
|
output_asm_insn (nop_templ, NULL);
|
||
|
}
|
||
|
|
||
|
+/* Write PATCH_AREA_SIZE NOPs into the asm outfile FILE around a function
|
||
|
+ entry. If RECORD_P is true and the target supports named sections,
|
||
|
+ the location of the NOPs will be recorded in a special object section
|
||
|
+ called "__patchable_function_entries". This routine may be called
|
||
|
+ twice per function to put NOPs before and after the function
|
||
|
+ entry. */
|
||
|
+
|
||
|
+void
|
||
|
+default_print_patchable_function_entry (FILE *file,
|
||
|
+ unsigned HOST_WIDE_INT patch_area_size,
|
||
|
+ bool record_p)
|
||
|
+{
|
||
|
+ unsigned int flags = SECTION_WRITE | SECTION_RELRO;
|
||
|
+ if (HAVE_GAS_SECTION_LINK_ORDER)
|
||
|
+ flags |= SECTION_LINK_ORDER;
|
||
|
+ default_print_patchable_function_entry_1 (file, patch_area_size, record_p,
|
||
|
+ flags);
|
||
|
+}
|
||
|
+
|
||
|
bool
|
||
|
default_profile_before_prologue (void)
|
||
|
{
|
||
|
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
|
||
|
index 6206fe20823..7b6d2fb9138 100644
|
||
|
--- a/gcc/targhooks.h
|
||
|
+++ b/gcc/targhooks.h
|
||
|
@@ -203,6 +203,9 @@ extern bool default_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
|
||
|
bool);
|
||
|
extern int default_compare_by_pieces_branch_ratio (machine_mode);
|
||
|
|
||
|
+extern void default_print_patchable_function_entry_1 (FILE *,
|
||
|
+ unsigned HOST_WIDE_INT,
|
||
|
+ bool, unsigned int);
|
||
|
extern void default_print_patchable_function_entry (FILE *,
|
||
|
unsigned HOST_WIDE_INT,
|
||
|
bool);
|
||
|
diff --git a/gcc/testsuite/g++.dg/pr93195a.C b/gcc/testsuite/g++.dg/pr93195a.C
|
||
|
index 26d265da74e..b14f1b3e341 100644
|
||
|
--- a/gcc/testsuite/g++.dg/pr93195a.C
|
||
|
+++ b/gcc/testsuite/g++.dg/pr93195a.C
|
||
|
@@ -1,4 +1,5 @@
|
||
|
/* { dg-do link { target { ! { nvptx*-*-* visium-*-* } } } } */
|
||
|
+/* { dg-skip-if "not supported" { { powerpc*-*-* } && lp64 } } */
|
||
|
// { dg-require-effective-target o_flag_in_section }
|
||
|
/* { dg-options "-O0 -fpatchable-function-entry=1" } */
|
||
|
/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
|
||
|
--
|
||
|
2.33.1
|
||
|
|