arch/m68k/include/asm/linkage.h | 2 ++ 1 file changed, 2 insertions(+)
Both GCC [1] and Clang [2] consider the generic version of _THIS_IP_ to
be broken:
#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })
In particular, the address of a label is only expected to be used with a
computed goto.
While the generic version more or less works today, it is known to be
brittle and may break with current and future optimizations. For
example, Clang -O2 always returns 1 when this function is inlined:
static inline unsigned long get_ip(void)
{ return ({ __label__ __here; __here: (unsigned long)&&__here; }); }
Fix it by overriding _THIS_IP_ in <asm/linkage.h> (which is included by
<linux/instruction_pointer.h>) using an architecture-specific inline asm
version. Additionally, avoiding taking the address of a label prevents
compilers from emitting spurious indirect branch targets (e.g. ENDBR or
BTI) under control-flow integrity schemes.
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120071 [1]
Link: https://github.com/llvm/llvm-project/issues/138272 [2]
Signed-off-by: Marco Elver <elver@google.com>
---
arch/m68k/include/asm/linkage.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/m68k/include/asm/linkage.h b/arch/m68k/include/asm/linkage.h
index c8b84282764c..9ed2f36830d0 100644
--- a/arch/m68k/include/asm/linkage.h
+++ b/arch/m68k/include/asm/linkage.h
@@ -35,4 +35,6 @@
__asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2), "m" (arg3), \
"m" (arg4), "m" (arg5), "m" (arg6))
+#define _THIS_IP_ ({ unsigned long __ip; asm volatile("lea %%pc@(.), %0" : "=a" (__ip)); __ip; })
+
#endif
--
2.54.0.746.g67dd491aae-goog
On Mai 21 2026, Marco Elver wrote: > version. Additionally, avoiding taking the address of a label prevents > compilers from emitting spurious indirect branch targets (e.g. ENDBR or > BTI) under control-flow integrity schemes. Ignoring the fact that m68k will never gain such a feature, dot is still a label. If you want to avoid a label, you need to use %pc(0) (or %pc(-2) for an address at insn boundary). -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different."
On Thu, 21 May 2026 17:14:33 +0200 Andreas Schwab <schwab@linux-m68k.org> wrote: > On Mai 21 2026, Marco Elver wrote: > > > version. Additionally, avoiding taking the address of a label prevents > > compilers from emitting spurious indirect branch targets (e.g. ENDBR or > > BTI) under control-flow integrity schemes. > > Ignoring the fact that m68k will never gain such a feature, dot is still > a label. But it wont be one the compiler sees. I think it is an assembler variable that is automatically updated, so not actually a label that ends up in the symbol table. Even the '1b:' in some of the other examples are only second class labels. -- David > If you want to avoid a label, you need to use %pc(0) (or > %pc(-2) for an address at insn boundary). >
On Thu, 21 May 2026 at 17:14, Andreas Schwab <schwab@linux-m68k.org> wrote: > > On Mai 21 2026, Marco Elver wrote: > > > version. Additionally, avoiding taking the address of a label prevents > > compilers from emitting spurious indirect branch targets (e.g. ENDBR or > > BTI) under control-flow integrity schemes. > > Ignoring the fact that m68k will never gain such a feature, dot is still > a label. If you want to avoid a label, you need to use %pc(0) (or > %pc(-2) for an address at insn boundary). The problematic label here is a C-label. The inline asm can use labels just fine, and would never affect codegen as stated. If this version looks correct to you, feel free to strip the CFI sentence from the patch description. Thanks, -- Marco
© 2016 - 2026 Red Hat, Inc.