diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-04-03 10:03:15 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-04-03 10:03:15 +0200 |
commit | b680b9049737198d010e49cf434704c6a6ed2b3f (patch) | |
tree | cbe038c349ac05a21ff64aee9ec0d9eff87b5e86 /gcc/targhooks.c | |
parent | 04771106cda8dca2c8b975fd4648933679455b8f (diff) | |
download | gcc-b680b9049737198d010e49cf434704c6a6ed2b3f.zip gcc-b680b9049737198d010e49cf434704c6a6ed2b3f.tar.gz gcc-b680b9049737198d010e49cf434704c6a6ed2b3f.tar.bz2 |
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.
Diffstat (limited to 'gcc/targhooks.c')
-rw-r--r-- | gcc/targhooks.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/gcc/targhooks.c b/gcc/targhooks.c index d69c9a2..952fad4 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1832,17 +1832,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; @@ -1864,9 +1862,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); @@ -1883,6 +1878,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) { |