internal/gocore/reverse.go
func (p *Process) ForEachReversePtr(y Object, fn func(x Object, r *Root, i, j int64) bool) {
	p.reverseEdges()

	idx, _ := p.findObjectIndex(p.Addr(y))
	for _, a := range p.redge[p.ridx[idx]:p.ridx[idx+1]] {
		// Read pointer, compute offset in y.
		ptr := p.proc.ReadPtr(a)
		j := ptr.Sub(p.Addr(y))

		// Find source of pointer.
		x, i := p.FindObject(a)
		if x != 0 {
			// Source is an object.
			if !fn(x, nil, i, j) {
				return
			}
			continue
		}
		// Source is a root.
		k := sort.Search(len(p.rootIdx), func(k int) bool {
			r := p.rootIdx[k]
			return a < r.Addr.Add(r.Type.Size)
		})
		r := p.rootIdx[k]
		if !fn(0, r, a.Sub(r.Addr), j) {
			return
		}
	}
}
func (p *Process) ForEachReversePtr(y Object, fn func(x Object, r *Root, i, j int64) bool) {
	p.reverseEdges()

	idx, _ := p.findObjectIndex(p.Addr(y))
	for _, a := range p.redge[p.ridx[idx]:p.ridx[idx+1]] {
		// Read pointer, compute offset in y.
		ptr := p.proc.ReadPtr(a)
		j := ptr.Sub(p.Addr(y))

		// Find source of pointer.
		x, i := p.FindObject(a)
		if x != 0 {
			// Source is an object.
			if !fn(x, nil, i, j) {
				return
			}
			continue
		}
		// Source is a root.
		k := sort.Search(len(p.rootIdx), func(k int) bool {
			r := p.rootIdx[k]
			return a < r.Addr.Add(r.Type.Size)
		})
		r := p.rootIdx[k]
		if !fn(0, r, a.Sub(r.Addr), j) {
			return
		}
	}
}
// ForEachReversePtr calls fn for all pointers it finds pointing to y.
// It calls fn with:
//   the object or root which points to y (exactly one will be non-nil)
//   the offset i in that object or root where the pointer appears.
//   the offset j in y where the pointer points.
// If fn returns false, ForEachReversePtr returns immediately.