From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2100) id 4F047385842D; Mon, 18 Oct 2021 21:12:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4F047385842D Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Giuliano Belinassi To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/giulianob/heads/pfe_backport_dirty)] Fix unwinding issues when pfe is enabled. X-Act-Checkin: gcc X-Git-Author: Giuliano Belinassi X-Git-Refname: refs/users/giulianob/heads/pfe_backport_dirty X-Git-Oldrev: 678444b35f863dde6d3eb17cfa0766e8e16ba177 X-Git-Newrev: 7703164761a3068696e964487dbbe6e732e0257b Message-Id: <20211018211227.4F047385842D@sourceware.org> Date: Mon, 18 Oct 2021 21:12:27 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Oct 2021 21:12:27 -0000 https://gcc.gnu.org/g:7703164761a3068696e964487dbbe6e732e0257b commit 7703164761a3068696e964487dbbe6e732e0257b Author: Giuliano Belinassi Date: Mon Oct 18 18:00:28 2021 -0300 Fix unwinding issues when pfe is enabled. This patch has basically the same behaviour as 3dcea658c, but avoid relying on the backend and CET mechanisms which are not implemented in gcc-7. Authored-by: Michael Matz Diff: --- gcc/ChangeLog | 6 ++ gcc/final.c | 4 ++ gcc/testsuite/ChangeLog | 18 ++++++ gcc/testsuite/gcc.target/i386/pr93492-1.c | 76 ++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr93492-2.c | 12 ++++ gcc/testsuite/gcc.target/i386/pr93492-3.c | 13 +++++ gcc/testsuite/gcc.target/i386/pr93492-4.c | 11 ++++ gcc/testsuite/gcc.target/i386/pr93492-5.c | 12 ++++ gcc/varasm.c | 91 ++++++++++++++++++------------- 9 files changed, 205 insertions(+), 38 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b993e85d2dc..a8487846716 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2021-10-18 Michael Matz + + * final.c (get_some_local_dynamic_name): Call + emit_patchable_function_entry. + * varasm.c (emit_patchable_function_entry): New. + 2021-10-07 Giuliano Belinassi Backport from mainline diff --git a/gcc/final.c b/gcc/final.c index 43743f05d84..53528620545 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1745,6 +1745,8 @@ get_some_local_dynamic_name () return 0; } +void emit_patchable_function_entry (tree decl, bool before); + /* Output assembler code for the start of a function, and initialize some of the variables in this file for the new function. The label for the function and associated @@ -1781,6 +1783,8 @@ final_start_function (rtx_insn *first, FILE *file, if (!dwarf2_debug_info_emitted_p (current_function_decl)) dwarf2out_begin_prologue (0, 0, NULL); + emit_patchable_function_entry (current_function_decl, false); + #ifdef LEAF_REG_REMAP if (crtl->uses_only_leaf_regs) leaf_renumber_regs (first); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 37920a12d61..540d58d461f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2021-10-18 Giuliano Belinassi + + Backport from mainline + 2020-02-03 H.J. Lu + + PR target/93492 + * gcc.target/i386/pr93492-1.c: New test. + * gcc.target/i386/pr93492-2.c: Likewise. + * gcc.target/i386/pr93492-3.c: Likewise. + * gcc.target/i386/pr93492-4.c: Likewise. + * gcc.target/i386/pr93492-5.c: Likewise. + + + PR target/93492 + * c-c++-common/patchable_function_entry-error-1.c: New test. + * c-c++-common/patchable_function_entry-error-2.c: Likewise. + * c-c++-common/patchable_function_entry-error-3.c: Likewise. + 2021-10-07 Giuliano Belinassi Backport from mainline diff --git a/gcc/testsuite/gcc.target/i386/pr93492-1.c b/gcc/testsuite/gcc.target/i386/pr93492-1.c new file mode 100644 index 00000000000..3383b0dc27b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr93492-1.c @@ -0,0 +1,76 @@ +/* { dg-do "compile" } */ +/* { dg-options "-O1" } */ + +/* Note: this test only checks the instructions in the function bodies, + not the placement of the patch label or nops before the function. */ + +/* +**f10_none: +** nop +** ret +*/ +void +__attribute__ ((patchable_function_entry (1, 0))) +f10_none (void) +{ +} + +/* +**f10_endbr: +** endbr(32|64) +** nop +** ret +*/ +void +__attribute__ ((patchable_function_entry (1, 0))) +f10_endbr (void) +{ +} + +/* +**f11_none: +** ret +*/ +void +__attribute__ ((patchable_function_entry (1, 1))) +f11_none (void) +{ +} + +/* +**f11_endbr: +** endbr(32|64) +** ret +*/ +void +__attribute__ ((patchable_function_entry (1, 1))) +f11_endbr (void) +{ +} + +/* +**f21_none: +** nop +** ret +*/ +void +__attribute__ ((patchable_function_entry (2, 1))) +f21_none (void) +{ +} + +/* +**f21_endbr: +** endbr(32|64) +** nop +** ret +*/ +void +__attribute__ ((patchable_function_entry (2, 1))) +f21_endbr (void) +{ +} + +/* { dg-final { scan-assembler "\.LPFE1:\n\tnop\n\trep ret" } } */ +/* { dg-final { scan-assembler "\.LPFE2:\n\tnop\n\trep ret" } } */ +/* { dg-final { scan-assembler "f11_none:\n\.LFB2:\n\t\.cfi_startproc\n\trep ret" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr93492-2.c b/gcc/testsuite/gcc.target/i386/pr93492-2.c new file mode 100644 index 00000000000..d52d7a41637 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr93492-2.c @@ -0,0 +1,12 @@ +/* { dg-do "compile" } */ +/* { dg-options "-O1 -fasynchronous-unwind-tables -Wno-attributes" } */ + +/* Test the placement of the .LPFE1 label. */ + +void +__attribute__ ((cf_check,patchable_function_entry (1, 0))) +f10_endbr (void) +{ +} + +/* { dg-final { scan-assembler "\.cfi_startproc\n.*\.LPFE1:\n\tnop\n\trep ret" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr93492-3.c b/gcc/testsuite/gcc.target/i386/pr93492-3.c new file mode 100644 index 00000000000..d391e117004 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr93492-3.c @@ -0,0 +1,13 @@ +/* { dg-do "compile" } */ +/* { dg-require-effective-target mfentry } */ +/* { dg-options "-O1 -mfentry -pg -fasynchronous-unwind-tables -Wno-attributes" } */ + +/* Test the placement of the .LPFE1 label. */ + +void +__attribute__ ((cf_check,patchable_function_entry (1, 0))) +f10_endbr (void) +{ +} + +/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE1:\n\tnop\n1:\tcall\t__fentry__\n\trep ret\n" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr93492-4.c b/gcc/testsuite/gcc.target/i386/pr93492-4.c new file mode 100644 index 00000000000..d5bfc58f7d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr93492-4.c @@ -0,0 +1,11 @@ +/* { dg-do "compile" } */ +/* { dg-options "-O1 -fpatchable-function-entry=1 -fasynchronous-unwind-tables -Wno-attributes" } */ + +/* Test the placement of the .LPFE1 label. */ + +void +foo (void) +{ +} + +/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE1:\n\tnop\n\trep ret\n" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr93492-5.c b/gcc/testsuite/gcc.target/i386/pr93492-5.c new file mode 100644 index 00000000000..0eb900b5a45 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr93492-5.c @@ -0,0 +1,12 @@ +/* { dg-do "compile" } */ +/* { dg-require-effective-target mfentry } */ +/* { dg-options "-O1 -fpatchable-function-entry=1 -mfentry -pg -fasynchronous-unwind-tables -Wno-attributes" } */ + +/* Test the placement of the .LPFE1 label. */ + +void +foo (void) +{ +} + +/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE1:\n\tnop\n1:\tcall\t__fentry__\n\trep ret\n" } } */ diff --git a/gcc/varasm.c b/gcc/varasm.c index 9e0e7c0976f..e197fbdaed5 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -1698,6 +1698,58 @@ get_fnname_from_decl (tree decl) return XSTR (x, 0); } +/* Emit the patchable function entry NOPs for function DECL. + BEFORE is true if we should emit the nops in front of the function + label (i.e. before prologue), or the ones after the function label + (part of the prologue). */ +void +emit_patchable_function_entry (tree decl, bool before) +{ + unsigned short patch_area_size = crtl->patch_area_size; + unsigned short patch_area_entry = crtl->patch_area_entry; + + tree patchable_function_entry_attr + = lookup_attribute ("patchable_function_entry", DECL_ATTRIBUTES (decl)); + if (patchable_function_entry_attr) + { + tree pp_val = TREE_VALUE (patchable_function_entry_attr); + tree patchable_function_entry_value1 = TREE_VALUE (pp_val); + + patch_area_size = tree_to_uhwi (patchable_function_entry_value1); + patch_area_entry = 0; + if (TREE_CHAIN (pp_val) != NULL_TREE) + { + tree patchable_function_entry_value2 + = TREE_VALUE (TREE_CHAIN (pp_val)); + patch_area_entry = tree_to_uhwi (patchable_function_entry_value2); + } + } + + if (patch_area_entry > patch_area_size) + { + if (patch_area_size > 0 && before) + warning (OPT_Wattributes, "patchable function entry > size"); + patch_area_entry = 0; + } + + if (before) + { + /* Emit the patching area before the entry label, if any. */ + if (patch_area_entry > 0) + targetm.asm_out.print_patchable_function_entry (asm_out_file, + patch_area_entry, true); + } + else + { + /* And the area after the label. Record it if we haven't done so yet. */ + if (patch_area_size > patch_area_entry) + targetm.asm_out.print_patchable_function_entry (asm_out_file, + patch_area_size + - patch_area_entry, + patch_area_entry == 0); + } +} + /* Output assembler code for the constant pool of a function and associated with defining the name of the function. DECL describes the function. NAME is the function's name. For the constant pool, we use the current @@ -1829,37 +1881,7 @@ assemble_start_function (tree decl, const char *fnname) if (DECL_PRESERVE_P (decl)) targetm.asm_out.mark_decl_preserved (fnname); - unsigned short patch_area_size = crtl->patch_area_size; - unsigned short patch_area_entry = crtl->patch_area_entry; - - tree patchable_function_entry_attr - = lookup_attribute ("patchable_function_entry", DECL_ATTRIBUTES (decl)); - if (patchable_function_entry_attr) - { - tree pp_val = TREE_VALUE (patchable_function_entry_attr); - tree patchable_function_entry_value1 = TREE_VALUE (pp_val); - - patch_area_size = tree_to_uhwi (patchable_function_entry_value1); - patch_area_entry = 0; - if (TREE_CHAIN (pp_val) != NULL_TREE) - { - tree patchable_function_entry_value2 - = TREE_VALUE (TREE_CHAIN (pp_val)); - patch_area_entry = tree_to_uhwi (patchable_function_entry_value2); - } - } - - if (patch_area_entry > patch_area_size) - { - if (patch_area_size > 0) - warning (OPT_Wattributes, "patchable function entry > size"); - patch_area_entry = 0; - } - - /* Emit the patching area before the entry label, if any. */ - if (patch_area_entry > 0) - targetm.asm_out.print_patchable_function_entry (asm_out_file, - patch_area_entry, true); + emit_patchable_function_entry (decl, true); /* Do any machine/system dependent processing of the function name. */ #ifdef ASM_DECLARE_FUNCTION_NAME @@ -1869,13 +1891,6 @@ assemble_start_function (tree decl, const char *fnname) ASM_OUTPUT_FUNCTION_LABEL (asm_out_file, fnname, current_function_decl); #endif /* ASM_DECLARE_FUNCTION_NAME */ - /* And the area after the label. Record it if we haven't done so yet. */ - if (patch_area_size > patch_area_entry) - targetm.asm_out.print_patchable_function_entry (asm_out_file, - patch_area_size - - patch_area_entry, - patch_area_entry == 0); - if (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (decl))) saw_no_split_stack = true; }