https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128360
Bug ID: 128360
Summary: i386: __attribute__((cf_check)) on static/localized
function silently omits ENDBR under
-fcf-protection=branch -mmanual-endbr
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: 220245569 at seu dot edu.cn
CC: 220255623 at seu dot edu.cn, jianhao.xu at seu dot edu.cn
Target Milestone: ---
Target: x86_64-*-* i?86-*-*
Reproducer
----------
$ cat trigger.c
static __attribute__((cf_check, noinline)) int
static_cf_target (int x)
{
__asm__ volatile ("" : "+r" (x));
return x + 1;
}
__attribute__((cf_check, noinline)) int
extern_cf_target (int x)
{
__asm__ volatile ("" : "+r" (x));
return x + 2;
}
int
caller (int x)
{
return static_cf_target (x) + extern_cf_target (x);
}
Compile flag: x86_64-linux-gnu-gcc -O2 -fcf-protection=branch -mmanual-endbr -S
trigger.c
static_cf_target:
.LFB0:
.cfi_startproc
leal 1(%rdi), %eax # missing endbr64 despite cf_check
ret
.cfi_endproc
extern_cf_target:
.LFB1:
.cfi_startproc
endbr64 # emitted as expected
leal 2(%rdi), %eax
ret
.cfi_endproc
Root cause
----------
In rest_of_insert_endbr_and_patchable_area
(gcc/config/i386/i386-features.cc:3014-3025),
the cf_check check is conjoined with !cgraph_node::get
(cfun->decl)->only_called_directly_p ():
if (!lookup_attribute ("nocf_check",
TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
&& (!flag_manual_endbr
|| lookup_attribute ("cf_check",
DECL_ATTRIBUTES (cfun->decl)))
&& (!cgraph_node::get (cfun->decl)->only_called_directly_p ()
|| ...))
When a static function (or a function localized by -fwhole-program / LTO) is
annotated with cf_check (e.g. reached via inline-asm indirect branch), GCC
still drops endbr64 whenever the middle-end sees only direct calls.
Suggested Fix
-------------
In rest_of_insert_endbr_and_patchable_area
(gcc/config/i386/i386-features.cc:3019),
exempt functions carrying an explicit cf_check attribute on DECL_ATTRIBUTES
(cfun->decl)
from the only_called_directly_p () check.