pmos/temp/gcc6/0013-i386-Don-t-generate-alias-for-function-return-thunk.patch
Oliver Smith 5cef6135da
temp/gcc6: add until Alpine builds it for arm
Copy Alpine's gcc6 aport to temp. They don't have it built for aarch64
and armhf at the moment. Due to dependency checks, this means we can't
build the kernels that need gcc6, even when cross compiling with
gcc6-armhf etc. See #138 for details.
2018-11-30 08:53:28 +01:00

226 lines
8.2 KiB
Diff

From e7fbaebc8ff650df76f43e92cb9ca59d5174ebe7 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 15 Mar 2018 17:54:40 +0000
Subject: [PATCH 13/13] i386: Don't generate alias for function return thunk
Function return thunks shouldn't be aliased to indirect branch thunks
since indirect branch thunks are placed in COMDAT section and a COMDAT
section with indirect branch may not have function return thunk. This
patch generates function return thunks directly.
gcc/
Backport from mainline
PR target/84574
* config/i386/i386.c (indirect_thunk_needed): Update comments.
(indirect_thunk_bnd_needed): Likewise.
(indirect_thunks_used): Likewise.
(indirect_thunks_bnd_used): Likewise.
(indirect_return_needed): New.
(indirect_return_bnd_needed): Likewise.
(output_indirect_thunk_function): Add a bool argument for
function return.
(output_indirect_thunk_function): Don't generate alias for
function return thunk.
(ix86_code_end): Call output_indirect_thunk_function to generate
function return thunks.
(ix86_output_function_return): Set indirect_return_bnd_needed
and indirect_return_needed instead of indirect_thunk_bnd_needed
and indirect_thunk_needed.
gcc/testsuite/
Backport from mainline
PR target/84574
* gcc.target/i386/ret-thunk-9.c: Expect __x86_return_thunk
label instead of __x86_indirect_thunk label.
---
gcc/config/i386/i386.c | 92 ++++++++++-------------------
gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2 +-
2 files changed, 33 insertions(+), 61 deletions(-)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 21c3c18bd3c..f4cd1c6f4e9 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11067,19 +11067,23 @@ ix86_setup_frame_addresses (void)
labels in call and return thunks. */
static int indirectlabelno;
-/* True if call and return thunk functions are needed. */
+/* True if call thunk function is needed. */
static bool indirect_thunk_needed = false;
-/* True if call and return thunk functions with the BND prefix are
- needed. */
+/* True if call thunk function with the BND prefix is needed. */
static bool indirect_thunk_bnd_needed = false;
/* Bit masks of integer registers, which contain branch target, used
- by call and return thunks functions. */
+ by call thunk functions. */
static int indirect_thunks_used;
/* Bit masks of integer registers, which contain branch target, used
- by call and return thunks functions with the BND prefix. */
+ by call thunk functions with the BND prefix. */
static int indirect_thunks_bnd_used;
+/* True if return thunk function is needed. */
+static bool indirect_return_needed = false;
+/* True if return thunk function with the BND prefix is needed. */
+static bool indirect_return_bnd_needed = false;
+
/* True if return thunk function via CX is needed. */
static bool indirect_return_via_cx;
/* True if return thunk function via CX with the BND prefix is
@@ -11226,16 +11230,18 @@ output_indirect_thunk (bool need_bnd_p, unsigned int regno)
/* Output a funtion with a call and return thunk for indirect branch.
If BND_P is true, the BND prefix is needed. If REGNO != INVALID_REGNUM,
the function address is in REGNO. Otherwise, the function address is
- on the top of stack. */
+ on the top of stack. Thunk is used for function return if RET_P is
+ true. */
static void
-output_indirect_thunk_function (bool need_bnd_p, unsigned int regno)
+output_indirect_thunk_function (bool need_bnd_p, unsigned int regno,
+ bool ret_p)
{
char name[32];
tree decl;
/* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */
- indirect_thunk_name (name, regno, need_bnd_p, false);
+ indirect_thunk_name (name, regno, need_bnd_p, ret_p);
decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
get_identifier (name),
build_function_type_list (void_type_node, NULL_TREE));
@@ -11278,50 +11284,6 @@ output_indirect_thunk_function (bool need_bnd_p, unsigned int regno)
ASM_OUTPUT_LABEL (asm_out_file, name);
}
- /* Create alias for __x86_return_thunk/__x86_return_thunk_bnd or
- __x86_return_thunk_ecx/__x86_return_thunk_ecx_bnd. */
- bool need_alias;
- if (regno == INVALID_REGNUM)
- need_alias = true;
- else if (regno == CX_REG)
- {
- if (need_bnd_p)
- need_alias = indirect_return_via_cx_bnd;
- else
- need_alias = indirect_return_via_cx;
- }
- else
- need_alias = false;
-
- if (need_alias)
- {
- char alias[32];
-
- indirect_thunk_name (alias, regno, need_bnd_p, true);
-#if TARGET_MACHO
- if (TARGET_MACHO)
- {
- fputs ("\t.weak_definition\t", asm_out_file);
- assemble_name (asm_out_file, alias);
- fputs ("\n\t.private_extern\t", asm_out_file);
- assemble_name (asm_out_file, alias);
- putc ('\n', asm_out_file);
- ASM_OUTPUT_LABEL (asm_out_file, alias);
- }
-#else
- ASM_OUTPUT_DEF (asm_out_file, alias, name);
- if (USE_HIDDEN_LINKONCE)
- {
- fputs ("\t.globl\t", asm_out_file);
- assemble_name (asm_out_file, alias);
- putc ('\n', asm_out_file);
- fputs ("\t.hidden\t", asm_out_file);
- assemble_name (asm_out_file, alias);
- putc ('\n', asm_out_file);
- }
-#endif
- }
-
DECL_INITIAL (decl) = make_node (BLOCK);
current_function_decl = decl;
allocate_struct_function (decl, false);
@@ -11368,19 +11330,29 @@ ix86_code_end (void)
rtx xops[2];
unsigned int regno;
+ if (indirect_return_needed)
+ output_indirect_thunk_function (false, INVALID_REGNUM, true);
+ if (indirect_return_bnd_needed)
+ output_indirect_thunk_function (true, INVALID_REGNUM, true);
+
+ if (indirect_return_via_cx)
+ output_indirect_thunk_function (false, CX_REG, true);
+ if (indirect_return_via_cx_bnd)
+ output_indirect_thunk_function (true, CX_REG, true);
+
if (indirect_thunk_needed)
- output_indirect_thunk_function (false, INVALID_REGNUM);
+ output_indirect_thunk_function (false, INVALID_REGNUM, false);
if (indirect_thunk_bnd_needed)
- output_indirect_thunk_function (true, INVALID_REGNUM);
+ output_indirect_thunk_function (true, INVALID_REGNUM, false);
for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
{
unsigned int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1;
if ((indirect_thunks_used & (1 << i)))
- output_indirect_thunk_function (false, regno);
+ output_indirect_thunk_function (false, regno, false);
if ((indirect_thunks_bnd_used & (1 << i)))
- output_indirect_thunk_function (true, regno);
+ output_indirect_thunk_function (true, regno, false);
}
for (regno = AX_REG; regno <= SP_REG; regno++)
@@ -11389,10 +11361,10 @@ ix86_code_end (void)
tree decl;
if ((indirect_thunks_used & (1 << regno)))
- output_indirect_thunk_function (false, regno);
+ output_indirect_thunk_function (false, regno, false);
if ((indirect_thunks_bnd_used & (1 << regno)))
- output_indirect_thunk_function (true, regno);
+ output_indirect_thunk_function (true, regno, false);
if (!(pic_labels_used & (1 << regno)))
continue;
@@ -28077,12 +28049,12 @@ ix86_output_function_return (bool long_p)
true);
if (need_bnd_p)
{
- indirect_thunk_bnd_needed |= need_thunk;
+ indirect_return_bnd_needed |= need_thunk;
fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
}
else
{
- indirect_thunk_needed |= need_thunk;
+ indirect_return_needed |= need_thunk;
fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
}
}
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
index d2df8b874e0..eee230ca2f6 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
@@ -13,7 +13,7 @@ foo (void)
/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */
+/* { dg-final { scan-assembler "__x86_return_thunk:" } } */
/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */
/* { dg-final { scan-assembler-times {\tpause} 2 } } */
/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
--
2.16.3