go-delve/delve · error

changing register %d not implemented

Error message

changing register %d not implemented

What it means

Delve's Windows ARM64 register writer only implements a fixed set of registers: the general-purpose registers plus V0..V30 float registers. SetReg reaches the default branch when the requested register number is outside the implemented set (e.g. V31, FPSR/FPCR, or other system registers), and throws this placeholder error.

Source

Thrown at pkg/proc/winutil/regs_arm64_arch.go:183

	case regnum.ARM64_PC:
		ctx.Pc = reg.Uint64Val
		return nil
	case regnum.ARM64_SP:
		ctx.Sp = reg.Uint64Val
		return nil
	default:
		switch {
		case regNum >= regnum.ARM64_X0 && regNum <= regnum.ARM64_X0+30:
			ctx.Regs[regNum-regnum.ARM64_X0] = reg.Uint64Val
			return nil

		case regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+30:
			i := regNum - regnum.ARM64_V0
			ctx.FloatRegisters[i].Low = reg.Uint64Val
			ctx.FloatRegisters[i].High = 0
			return nil
		default:
			return fmt.Errorf("changing register %d not implemented", regNum)
		}
	}
}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Do not attempt to set V31 or system/FPSR/FPCR registers through this API — they are not implemented on Windows ARM64.
  2. Restrict register writes to the implemented set: general-purpose registers and V0..V30.
  3. If the register truly needs modification, extend winutil regs_arm64_arch.go SetReg with a case mapping regNum to the corresponding CONTEXT FloatRegisters or system field.
  4. Verify the register index with regnum helpers before calling SetReg.

Example fix

// before
i := regNum - regnum.ARM64_V0 // regNum == ARM64_V0+31 -> falls to default
// after
if regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+30 {
    i := regNum - regnum.ARM64_V0
    ctx.FloatRegisters[i].Low = reg.Uint64Val
    ctx.FloatRegisters[i].High = 0
    return nil
}
return fmt.Errorf("register %s is not settable on windows/arm64", regnum.ARM64ToName(regNum))
Defensive patterns

Strategy: validation

Validate before calling

if regNum == regnum.ARM64_V0+31 || !(regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+30) {
    return fmt.Errorf("register %d is not settable on windows/arm64", regNum)
}

Type guard

func isSettableARM64Reg(regNum int) bool {
    return (regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+30) || isGPR(regNum)
}

Try / catch

if err := thread.SetReg(regNum, reg); err != nil {
    var notImpl interface{ Error() string }
    if strings.Contains(err.Error(), "not implemented") {
        // fall back: skip register or use a read-only view
    }
    return err
}

Prevention

When it happens

Trigger: Calling SetReg on a Windows/arm64 target with regNum not matching any handled case — notably regnum.ARM64_V0+31 (V31), or non-vector/non-GPR registers like FPCR/FPSR that the switch does not enumerate.

Common situations: Tooling that assumes all ARM64 registers are writable; attempts to set V31 (which aliases the zero register ZR in instructions and is excluded from the V0..V30 range); attempts to write floating-point status/control registers during debugging sessions on Windows ARM64.

Related errors


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