CALL    runtime·abort(SB)
        RET
 
-       // Prevent dead-code elimination of debugCallV2, which is
+       // Prevent dead-code elimination of debugCallV2 and debugPinnerV1, which are
        // intended to be called by debuggers.
+       MOVQ    $runtime·debugPinnerV1<ABIInternal>(SB), AX
        MOVQ    $runtime·debugCallV2<ABIInternal>(SB), AX
        RET
 
 
        // start this M
        BL      runtime·mstart(SB)
 
-       // Prevent dead-code elimination of debugCallV2, which is
+       // Prevent dead-code elimination of debugCallV2 and debugPinnerV1, which are
        // intended to be called by debuggers.
+       MOVD    $runtime·debugPinnerV1<ABIInternal>(SB), R0
        MOVD    $runtime·debugCallV2<ABIInternal>(SB), R0
 
        MOVD    $0, R0
 
 
        // start this M
        BL      runtime·mstart(SB)
-       // Prevent dead-code elimination of debugCallV2, which is
+       // Prevent dead-code elimination of debugCallV2 and debugPinnerV1, which are
        // intended to be called by debuggers.
 #ifdef GOARCH_ppc64le
+       MOVD    $runtime·debugPinnerV1<ABIInternal>(SB), R31
        MOVD    $runtime·debugCallV2<ABIInternal>(SB), R31
 #endif
        MOVD    R0, 0(R0)
 
                gp.stackguard0 = stackForceMove
        }
 }
+
+// debugPinnerKeepUnpin is used to make runtime.(*Pinner).Unpin reachable.
+var debugPinnerKeepUnpin bool = false
+
+// debugPinnerV1 returns a new Pinner that pins itself. This function can be
+// used by debuggers to easily obtain a Pinner that will not be garbage
+// collected (or moved in memory) even if no references to it exist in the
+// target program. This pinner in turn can be used to extend this property
+// to other objects, which debuggers can use to simplify the evaluation of
+// expressions involving multiple call injections.
+func debugPinnerV1() *Pinner {
+       p := new(Pinner)
+       p.Pin(unsafe.Pointer(p))
+       if debugPinnerKeepUnpin {
+               // Make Unpin reachable.
+               p.Unpin()
+       }
+       return p
+}