https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102953
--- Comment #22 from H.J. Lu <hjl.tools at gmail dot com> --- (In reply to Andrew Cooper from comment #21) > Another possibly-bug, but possibly mis-expectations on my behalf. > > I've found some code in the depths of Xen which is causing a failure on > final link due to a missing `__x86_indirect_thunk_nt_rax` symbol. > > $ cat fnptr-typeof.c > extern void (*fnptrs[])(char); > > void foo(int a) > { > typeof(foo) *bar = (void *)fnptrs[0]; > bar(a); > } > > I realise this is wildly undefined behaviour, and I will try to address it > in due course. However, the instruction generation is bizarre. > > When I compile with -fcf-protection=branch -mmanual-endbr, I get a plain > `jmp *fnptrs(%rip)` instruction. (This is fine.) > > When I compile with -fcf-check-attribute=no as well, then I get `notrack jmp > *fnptrs(%rip)`. I'm not sure why the notrack is warranted here; for all GCC > knows, the target does have a suitable ENDBR64 instruction. > >From "info gcc": The 'nocf_check' attribute on a type of pointer to function is used to inform the compiler that a call through the pointer should not be instrumented when compiled with the '-fcf-protection=branch' option. The compiler assumes that the function's address from the pointer is a valid target for a control-flow transfer. A direct function call through a function name is assumed to be a safe call thus direct calls are not instrumented by the compiler. That is why notrack is added.