]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: start ARM atomic kernel helper traceback in caller
authorMichael Pratt <mpratt@google.com>
Wed, 10 Nov 2021 17:56:40 +0000 (12:56 -0500)
committerMichael Pratt <mpratt@google.com>
Fri, 12 Nov 2021 21:06:35 +0000 (21:06 +0000)
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>
src/runtime/traceback.go

index 36627a6735960b13167701be20cd2ede615b8409..73bd0e11a9c9778b7184f1c3a25ca29a9636491d 100644 (file)
@@ -96,6 +96,20 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                }
        }
 
+       // 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 {