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/ 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. From-SVN: r258569
This commit is contained in:
parent
4a5a49b034
commit
23f95cb77a
@ -1,3 +1,22 @@
|
||||
2018-03-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
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.
|
||||
|
||||
2018-03-15 Olga Makhotina <olga.makhotina@intel.com>
|
||||
|
||||
* config/i386/sgxintrin.h (_enclv_u32): New intrinsic.
|
||||
|
@ -10819,19 +10819,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
|
||||
@ -11027,17 +11031,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));
|
||||
@ -11080,50 +11085,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);
|
||||
@ -11170,23 +11131,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++)
|
||||
@ -11196,11 +11171,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;
|
||||
@ -29060,12 +29035,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);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
2018-03-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/84574
|
||||
* gcc.target/i386/ret-thunk-9.c: Expect __x86_return_thunk
|
||||
label instead of __x86_indirect_thunk label.
|
||||
|
||||
2018-03-15 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/84222
|
||||
|
@ -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 } } */
|
||||
|
Loading…
Reference in New Issue
Block a user