2021-10-26 06:17:33 +00:00
|
|
|
From e534bd23ac8d259768d67db6f876f75687b109e7 Mon Sep 17 00:00:00 2001
|
2021-10-22 07:20:27 +00:00
|
|
|
From: Giuliano Belinassi <gbelinassi@suse.de>
|
|
|
|
Date: Mon, 18 Oct 2021 18:00:28 -0300
|
|
|
|
Subject: [PATCH 22/22] 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.
|
|
|
|
|
|
|
|
gcc/ChangeLog
|
|
|
|
2021-10-18 Michael Matz <matz@suse.de>
|
|
|
|
|
|
|
|
* final.c (get_some_local_dynamic_name): Call
|
|
|
|
emit_patchable_function_entry.
|
|
|
|
* varasm.c (emit_patchable_function_entry): New.
|
|
|
|
|
|
|
|
gcc/testsuite/ChangeLog
|
|
|
|
2021-10-18 Giuliano Belinassi <gbelinassi@suse.de>
|
|
|
|
|
|
|
|
Backport from mainline
|
|
|
|
2020-02-03 H.J. Lu <hjl.tools@gmail.com>
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
Authored-by: Michael Matz <matz@suse.de>
|
|
|
|
---
|
|
|
|
gcc/ChangeLog | 6 ++
|
|
|
|
gcc/final.c | 4 +
|
|
|
|
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 +++++++++++++----------
|
|
|
|
8 files changed, 187 insertions(+), 38 deletions(-)
|
|
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/pr93492-1.c
|
|
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/pr93492-2.c
|
|
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/pr93492-3.c
|
|
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/pr93492-4.c
|
|
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/pr93492-5.c
|
|
|
|
|
|
|
|
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
|
|
|
|
index 51fed5508dc..537c343e6f1 100644
|
|
|
|
--- a/gcc/ChangeLog
|
|
|
|
+++ b/gcc/ChangeLog
|
|
|
|
@@ -1,3 +1,9 @@
|
|
|
|
+2021-10-18 Michael Matz <matz@suse.de>
|
|
|
|
+
|
|
|
|
+ * final.c (get_some_local_dynamic_name): Call
|
|
|
|
+ emit_patchable_function_entry.
|
|
|
|
+ * varasm.c (emit_patchable_function_entry): New.
|
|
|
|
+
|
|
|
|
2019-11-14 Release Manager
|
|
|
|
|
|
|
|
* GCC 7.5.0 released.
|
|
|
|
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/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
|
2021-10-26 06:17:33 +00:00
|
|
|
index 00000000000..a3ba22da17d
|
2021-10-22 07:20:27 +00:00
|
|
|
--- /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)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+
|
2021-10-28 07:02:00 +00:00
|
|
|
+/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE1:\n\tnop\n1:\tcall\t__fentry__\n.*\t(rep )?ret\n" } } */
|
2021-10-22 07:20:27 +00:00
|
|
|
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
|
2021-10-26 06:17:33 +00:00
|
|
|
index 00000000000..69e706ff38e
|
2021-10-22 07:20:27 +00:00
|
|
|
--- /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)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+
|
2021-10-28 07:02:00 +00:00
|
|
|
+/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE1:\n\tnop\n1:\tcall\t__fentry__\n.*\t(rep )?ret\n" } } */
|
2021-10-22 07:20:27 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
--
|
|
|
|
2.33.1
|
|
|
|
|