https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83970
Bug ID: 83970 Summary: -mindirect-branch=thunk -fno-plt generates CET-incompatible thunk Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: hjl.tools at gmail dot com Target Milestone: --- Target: x86 [hjl@gnu-bdx-1 indirect-got-1]$ cat x.i void func (void); void bar (void) { func (); } [hjl@gnu-bdx-1 indirect-got-1]$ /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -mindirect-branch=thunk -fno-plt -S x.i [hjl@gnu-bdx-1 indirect-got-1]$ cat x.s .file "x.i" .text .p2align 4,,15 .globl bar .type bar, @function bar: .LFB0: .cfi_startproc pushq func@GOTPCREL(%rip) jmp __x86_indirect_thunk .cfi_endproc .LFE0: .size bar, .-bar .section .text.__x86_indirect_thunk,"axG",@progbits,__x86_indirect_thunk,comdat .globl __x86_indirect_thunk .hidden __x86_indirect_thunk .type __x86_indirect_thunk, @function __x86_indirect_thunk: .set __x86_return_thunk,__x86_indirect_thunk .globl __x86_return_thunk .hidden __x86_return_thunk .LFB1: .cfi_startproc call .LIND1 .LIND0: pause lfence jmp .LIND0 .LIND1: lea 8(%rsp), %rsp ret .cfi_endproc .LFE1: .ident "GCC: (GNU) 8.0.1 20180115 (experimental)" .section .note.GNU-stack,"",@progbits [hjl@gnu-bdx-1 indirect-got-1]$ For i386, since all registers may be used for function call, there isn't much we can do. But there are a couple scratch registers available for function call. We can generate bar: .LFB0: .cfi_startproc movq func@GOTPCREL(%rip), %r11 jmp __x86_indirect_thunk_r11 .cfi_endproc .LFE0: .size bar, .-bar which is easier to change __x86_indirect_thunk_r11 to be compatible with CET.