280 lines
13 KiB
Diff
280 lines
13 KiB
Diff
From c6b72be421ded17e0c156070ba6e90aa6c335ed6 Mon Sep 17 00:00:00 2001
|
|
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
|
|
Date: Tue, 16 Jan 2018 10:59:42 +0000
|
|
Subject: [PATCH 5/9] x86: Add -mindirect-branch= (documentation)
|
|
|
|
Add -mindirect-branch= option to convert indirect call and jump to call
|
|
and return thunks. The default is 'keep', which keeps indirect call and
|
|
jump unmodified. 'thunk' converts indirect call and jump to call and
|
|
return thunk. 'thunk-inline' converts indirect call and jump to inlined
|
|
call and return thunk. 'thunk-extern' converts indirect call and jump to
|
|
external call and return thunk provided in a separate object file. You
|
|
can control this behavior for a specific function by using the function
|
|
attribute indirect_branch.
|
|
|
|
2 kinds of thunks are geneated. Memory thunk where the function address
|
|
is at the top of the stack:
|
|
|
|
__x86_indirect_thunk:
|
|
call L2
|
|
L1:
|
|
pause
|
|
lfence
|
|
jmp L1
|
|
L2:
|
|
lea 8(%rsp), %rsp|lea 4(%esp), %esp
|
|
ret
|
|
|
|
Indirect jmp via memory, "jmp mem", is converted to
|
|
|
|
push memory
|
|
jmp __x86_indirect_thunk
|
|
|
|
Indirect call via memory, "call mem", is converted to
|
|
|
|
jmp L2
|
|
L1:
|
|
push [mem]
|
|
jmp __x86_indirect_thunk
|
|
L2:
|
|
call L1
|
|
|
|
Register thunk where the function address is in a register, reg:
|
|
|
|
__x86_indirect_thunk_reg:
|
|
call L2
|
|
L1:
|
|
pause
|
|
lfence
|
|
jmp L1
|
|
L2:
|
|
movq %reg, (%rsp)|movl %reg, (%esp)
|
|
ret
|
|
|
|
where reg is one of (r|e)ax, (r|e)dx, (r|e)cx, (r|e)bx, (r|e)si, (r|e)di,
|
|
(r|e)bp, r8, r9, r10, r11, r12, r13, r14 and r15.
|
|
|
|
Indirect jmp via register, "jmp reg", is converted to
|
|
|
|
jmp __x86_indirect_thunk_reg
|
|
|
|
Indirect call via register, "call reg", is converted to
|
|
|
|
call __x86_indirect_thunk_reg
|
|
|
|
gcc/
|
|
|
|
Backport from mainline
|
|
* config/i386/i386-opts.h (indirect_branch): New.
|
|
* config/i386/i386-protos.h (ix86_output_indirect_jmp): Likewise.
|
|
* config/i386/i386.c (ix86_using_red_zone): Disallow red-zone
|
|
with local indirect jump when converting indirect call and jump.
|
|
(ix86_set_indirect_branch_type): New.
|
|
(ix86_set_current_function): Call ix86_set_indirect_branch_type.
|
|
(indirectlabelno): New.
|
|
(indirect_thunk_needed): Likewise.
|
|
(indirect_thunk_bnd_needed): Likewise.
|
|
(indirect_thunks_used): Likewise.
|
|
(indirect_thunks_bnd_used): Likewise.
|
|
(INDIRECT_LABEL): Likewise.
|
|
(indirect_thunk_name): Likewise.
|
|
(output_indirect_thunk): Likewise.
|
|
(output_indirect_thunk_function): Likewise.
|
|
(ix86_output_indirect_branch_via_reg): Likewise.
|
|
(ix86_output_indirect_branch_via_push): Likewise.
|
|
(ix86_output_indirect_branch): Likewise.
|
|
(ix86_output_indirect_jmp): Likewise.
|
|
(ix86_code_end): Call output_indirect_thunk_function if needed.
|
|
(ix86_output_call_insn): Call ix86_output_indirect_branch if
|
|
needed.
|
|
(ix86_handle_fndecl_attribute): Handle indirect_branch.
|
|
(ix86_attribute_table): Add indirect_branch.
|
|
* config/i386/i386.h (machine_function): Add indirect_branch_type
|
|
and has_local_indirect_jump.
|
|
* config/i386/i386.md (indirect_jump): Set has_local_indirect_jump
|
|
to true.
|
|
(tablejump): Likewise.
|
|
(*indirect_jump): Use ix86_output_indirect_jmp.
|
|
(*tablejump_1): Likewise.
|
|
(simple_return_indirect_internal): Likewise.
|
|
* config/i386/i386.opt (mindirect-branch=): New option.
|
|
(indirect_branch): New.
|
|
(keep): Likewise.
|
|
(thunk): Likewise.
|
|
(thunk-inline): Likewise.
|
|
(thunk-extern): Likewise.
|
|
* doc/extend.texi: Document indirect_branch function attribute.
|
|
* doc/invoke.texi: Document -mindirect-branch= option.
|
|
|
|
gcc/testsuite/
|
|
|
|
Backport from mainline
|
|
* gcc.target/i386/indirect-thunk-1.c: New test.
|
|
* gcc.target/i386/indirect-thunk-2.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-3.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-4.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-5.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-6.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-7.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-attr-1.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-attr-2.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-attr-3.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-attr-4.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-attr-5.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-attr-6.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-attr-7.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-attr-8.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-bnd-1.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-bnd-2.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-bnd-3.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-bnd-4.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-extern-1.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-extern-2.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-extern-3.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-extern-4.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-extern-5.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-extern-6.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-inline-1.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-inline-2.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-inline-3.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-inline-4.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-inline-5.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-inline-6.c: Likewise.
|
|
* gcc.target/i386/indirect-thunk-inline-7.c: Likewise.
|
|
|
|
|
|
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256732 138bc75d-0d04-0410-961f-82ee72b054a4
|
|
|
|
[UBUNTU NOTES: Updated for gcc-5.4 to include defines for
|
|
FIRST_INT_REG, LAST_INT_REG, and LEGACY_INT_REGNO_P as defined in
|
|
https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=222269.
|
|
Dropped indirect-thunk-5.c, indirect-thunk-6.c,
|
|
indirect-thunk-bnd-3.c, indirect-thunk-bnd-4.c,
|
|
indirect-thunk-extern-5.c, indirect-thunk-extern-6.c,
|
|
indirect-thunk-inline-5.c, and indirect-thunk-inline-6.c tests due
|
|
to gcc 5.4 and earlier not supporting the -fno-plt option.
|
|
--sbeattie, tyhicks]
|
|
---
|
|
src/gcc/config/i386/i386-opts.h | 13
|
|
src/gcc/config/i386/i386-protos.h | 1
|
|
src/gcc/config/i386/i386.c | 621 +++++++++++-
|
|
src/gcc/config/i386/i386.h | 12
|
|
src/gcc/config/i386/i386.md | 26
|
|
src/gcc/config/i386/i386.opt | 20
|
|
src/gcc/doc/extend.texi | 10
|
|
src/gcc/doc/invoke.texi | 14
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 20
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 20
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 21
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 21
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 44
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 23
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 21
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 23
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 22
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 22
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 21
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 44
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 42
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 20
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 21
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 19
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 19
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 20
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 20
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 43
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 20
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 20
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 21
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 21
|
|
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 44
|
|
33 files changed, 1334 insertions(+), 15 deletions(-)
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
|
|
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
|
|
|
|
Index: b/src/gcc/doc/extend.texi
|
|
===================================================================
|
|
--- a/src/gcc/doc/extend.texi
|
|
+++ b/src/gcc/doc/extend.texi
|
|
@@ -4119,6 +4119,16 @@ Specify which floating-point unit to use
|
|
@code{target("fpmath=sse,387")} option must be specified as
|
|
@code{target("fpmath=sse+387")} because the comma would separate
|
|
different options.
|
|
+
|
|
+@item indirect_branch("@var{choice}")
|
|
+@cindex @code{indirect_branch} function attribute, x86
|
|
+On x86 targets, the @code{indirect_branch} attribute causes the compiler
|
|
+to convert indirect call and jump with @var{choice}. @samp{keep}
|
|
+keeps indirect call and jump unmodified. @samp{thunk} converts indirect
|
|
+call and jump to call and return thunk. @samp{thunk-inline} converts
|
|
+indirect call and jump to inlined call and return thunk.
|
|
+@samp{thunk-extern} converts indirect call and jump to external call
|
|
+and return thunk provided in a separate object file.
|
|
@end table
|
|
|
|
On the PowerPC, the following options are allowed:
|
|
Index: b/src/gcc/doc/invoke.texi
|
|
===================================================================
|
|
--- a/src/gcc/doc/invoke.texi
|
|
+++ b/src/gcc/doc/invoke.texi
|
|
@@ -1090,7 +1090,8 @@ See RS/6000 and PowerPC Options.
|
|
-m32 -m64 -mx32 -m16 -mlarge-data-threshold=@var{num} @gol
|
|
-msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol
|
|
-mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol
|
|
--malign-data=@var{type} -mstack-protector-guard=@var{guard}}
|
|
+-malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol
|
|
+-mindirect-branch=@var{choice}}
|
|
|
|
@emph{x86 Windows Options}
|
|
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
|
|
@@ -24017,6 +24018,17 @@ The default value of this option is enab
|
|
of the option is @option{-fno-sync-libcalls}. This option is used in
|
|
the implementation of the @file{libatomic} runtime library.
|
|
|
|
+@item -mindirect-branch=@var{choice}
|
|
+@opindex -mindirect-branch
|
|
+Convert indirect call and jump with @var{choice}. The default is
|
|
+@samp{keep}, which keeps indirect call and jump unmodified.
|
|
+@samp{thunk} converts indirect call and jump to call and return thunk.
|
|
+@samp{thunk-inline} converts indirect call and jump to inlined call
|
|
+and return thunk. @samp{thunk-extern} converts indirect call and jump
|
|
+to external call and return thunk provided in a separate object file.
|
|
+You can control this behavior for a specific function by using the
|
|
+function attribute @code{indirect_branch}. @xref{Function Attributes}.
|
|
+
|
|
@end table
|
|
|
|
@c man end
|