go-delve/delve · error

changing register %d not implemented

Error message

changing register %d not implemented

What it means

The ppc64le SetReg implementation supports general-purpose registers and VS0-VS31 (vector-scalar) registers only; unhandled register numbers fall to the default case and produce this error.

Source

Thrown at pkg/proc/linutil/regs_ppc64le_arch.go:200

			return false, nil

		case regNum >= regnum.PPC64LE_F0 && regNum <= regnum.PPC64LE_F0+31:
			if r.loadFpRegs != nil {
				err := r.loadFpRegs(r)
				r.loadFpRegs = nil
				if err != nil {
					return false, err
				}
			}
			// On ppc64le, PPC64LE_VS0 .. PPC64LE_VS31 are mapped onto
			// PPC64LE_F0 .. PPC64LE_F31
			i := regNum - regnum.PPC64LE_VS0
			reg.FillBytes()
			copy(r.Fpregset[8*i:], reg.Bytes)
			return true, nil

		default:
			return false, fmt.Errorf("changing register %d not implemented", regNum)
		}
	}
}

type PPC64LEPtraceFpRegs struct {
	Fp []byte
}

func (fpregs *PPC64LEPtraceFpRegs) Decode() (regs []proc.Register) {
	for i := 0; i < len(fpregs.Fp); i += 8 {
		regs = proc.AppendBytesRegister(regs, fmt.Sprintf("VS%d", i/8), fpregs.Fp[i:i+8])
	}
	return
}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Restrict SetReg usage to GPRs and VS0-VS31 on ppc64le
  2. Implement or use a dedicated path for SPR writes (e.g. PTRACE_SETREGSET with the right register set) if required
  3. Validate the regnum against the supported ranges before calling SetReg

Example fix

// before
thread.SetReg(regnum.PPC64LE_LR, reg) // not implemented here
// after
if regnum.PPC64LE_VS0 <= regNum && regNum <= regnum.PPC64LE_VS0+31 {
    thread.SetReg(regNum, reg)
} else {
    return fmt.Errorf("cannot set register %d on ppc64le", regNum)
}
Defensive patterns

Strategy: validation

Validate before calling

supported := isGPR(regNum) || (regNum >= regnum.PPC64LE_VS0 && regNum <= regnum.PPC64LE_VS0+31)
if !supported {
    return fmt.Errorf("register %d not settable on ppc64le", regNum)
}

Type guard

func isSettablePPC64LE(regNum uint64) bool {
    return isGPR(regNum) || (regNum >= regnum.PPC64LE_VS0 && regNum <= regnum.PPC64LE_VS0+31)
}

Try / catch

if _, err := thread.SetReg(regNum, reg); err != nil {
    if strings.Contains(err.Error(), "not implemented") {
        return fmt.Errorf("ppc64le register %d cannot be modified", regNum)
    }
    return err
}

Prevention

When it happens

Trigger: Calling SetReg on Linux/ppc64le with a register number outside the implemented GPR set and outside PPC64LE_VS0..VS0+31 (e.g. VSR upper half, SPE registers, special-purpose registers like LR/CTR when not routed).

Common situations: Trying to modify ppc64le special-purpose registers (LR, CTR, CR) through this code path; porting register-write code from another architecture.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/0fa43601e67f8f35. Report an issue: GitHub.