From: "H.J. Lu" <hongjiu.lu@intel.com>
To: gcc-patches@gcc.gnu.org
Cc: Jan Hubicka <hubicka@ucw.cz>
Subject: [PATCH] i386: Don't generate alias for function return thunk
Date: Mon, 26 Feb 2018 20:49:00 -0000 [thread overview]
Message-ID: <20180226204843.GA232084@intel.com> (raw)
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.
Tested on i686 and x86-64. OK for trunk?
H.J.
---
gcc/
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/
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 | 95 +++++++++++------------------
gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2 +-
2 files changed, 36 insertions(+), 61 deletions(-)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 49f872d103f..9041485bd61 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10799,19 +10799,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
@@ -11007,17 +11011,18 @@ output_indirect_thunk (enum indirect_thunk_prefix need_prefix,
/* Output a funtion with a call and return thunk for indirect branch.
If BND_P is true, the BND prefix is needed. If REGNO != UNVALID_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 (enum indirect_thunk_prefix need_prefix,
- unsigned int regno)
+ 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_prefix, false);
+ indirect_thunk_name (name, regno, need_prefix, ret_p);
decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
get_identifier (name),
build_function_type_list (void_type_node, NULL_TREE));
@@ -11060,50 +11065,6 @@ output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
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_prefix == indirect_thunk_prefix_bnd)
- 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_prefix, 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);
@@ -11150,23 +11111,37 @@ ix86_code_end (void)
rtx xops[2];
unsigned int regno;
+ if (indirect_return_needed)
+ output_indirect_thunk_function (indirect_thunk_prefix_none,
+ INVALID_REGNUM, true);
+ if (indirect_return_bnd_needed)
+ output_indirect_thunk_function (indirect_thunk_prefix_bnd,
+ INVALID_REGNUM, true);
+
+ if (indirect_return_via_cx)
+ output_indirect_thunk_function (indirect_thunk_prefix_none,
+ CX_REG, true);
+ if (indirect_return_via_cx_bnd)
+ output_indirect_thunk_function (indirect_thunk_prefix_bnd,
+ CX_REG, true);
+
if (indirect_thunk_needed)
output_indirect_thunk_function (indirect_thunk_prefix_none,
- INVALID_REGNUM);
+ INVALID_REGNUM, false);
if (indirect_thunk_bnd_needed)
output_indirect_thunk_function (indirect_thunk_prefix_bnd,
- INVALID_REGNUM);
+ 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 (indirect_thunk_prefix_none,
- regno);
+ regno, false);
if ((indirect_thunks_bnd_used & (1 << i)))
output_indirect_thunk_function (indirect_thunk_prefix_bnd,
- regno);
+ regno, false);
}
for (regno = FIRST_INT_REG; regno <= LAST_INT_REG; regno++)
@@ -11176,11 +11151,11 @@ ix86_code_end (void)
if ((indirect_thunks_used & (1 << regno)))
output_indirect_thunk_function (indirect_thunk_prefix_none,
- regno);
+ regno, false);
if ((indirect_thunks_bnd_used & (1 << regno)))
output_indirect_thunk_function (indirect_thunk_prefix_bnd,
- regno);
+ regno, false);
if (!(pic_labels_used & (1 << regno)))
continue;
@@ -29039,12 +29014,12 @@ ix86_output_function_return (bool long_p)
true);
if (need_prefix == indirect_thunk_prefix_bnd)
{
- 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 b75fc9219b0..819671af933 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.14.3
reply other threads:[~2018-02-26 20:49 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180226204843.GA232084@intel.com \
--to=hongjiu.lu@intel.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=hjl.tools@gmail.com \
--cc=hubicka@ucw.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).