Like the VDSO, we cannot directly traceback from the Linux kernel ARM
atomic/barrier helpers. However, unlike the VDSO, this functions are
extremely simple. Neither of the functions we use, kuser_cmpxchg and
kuser_memory_barrier, touch SP or LR.
We can use this to our advantage to read LR and simply start tracebacks
in the caller.
Fixes #49182
Change-Id: I890edbeb7c128938000fe7baf6f913c02a956edd
Reviewed-on: https://go-review.googlesource.com/c/go/+/362977
Trust: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
}
}
+ // runtime/internal/atomic functions call into kernel helpers on
+ // arm < 7. See runtime/internal/atomic/sys_linux_arm.s.
+ //
+ // Start in the caller's frame.
+ if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && frame.pc&0xffff0000 == 0xffff0000 {
+ // Note that the calls are simple BL without pushing the return
+ // address, so we use LR directly.
+ //
+ // The kernel helpers are frameless leaf functions, so SP and
+ // LR are not touched.
+ frame.pc = frame.lr
+ frame.lr = 0
+ }
+
f := findfunc(frame.pc)
if !f.valid() {
if callback != nil || printing {