go-delve/delve · error

changing register %d not implemented

Error message

changing register %d not implemented

What it means

The loong64 SetReg implementation only handles general-purpose and F0-F31 floating-point registers; any other register number reaches the default branch and is rejected as unimplemented.

Source

Thrown at pkg/proc/linutil/regs_loong64_arch.go:196

		r.Regs.Regs[regNum] = reg.Uint64Val
		return false, nil

	case regNum >= regnum.LOONG64_F0 && regNum <= regnum.LOONG64_F31:
		if r.loadFpRegs != nil {
			err := r.loadFpRegs(r)
			r.loadFpRegs = nil
			if err != nil {
				return false, err
			}
		}

		i := regNum - regnum.LOONG64_F0
		reg.FillBytes()
		copy(r.Fpregset[8*i:], reg.Bytes)
		return true, nil

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

// LOONG64PtraceFpRegs refers to the definition of struct user_fp_state in kernel ptrace.h
type LOONG64PtraceFpRegs struct {
	Fregs []byte
	Fcc   uint64
	Fcsr  uint32
}

const _LOONG64_FPREGSET_LENGTH = (32 * 8)

func (fpregs *LOONG64PtraceFpRegs) Decode() (regs []proc.Register) {
	for i := 0; i < len(fpregs.Fregs); i += 8 {
		name := fmt.Sprintf("F%d", (i / 8))
		value := fpregs.Fregs[i : i+8]
		regs = proc.AppendBytesRegister(regs, name, value)
	}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Only write GPRs and F0-F31 via SetReg on loong64
  2. Extend the native backend (and add kernel ptrace support) if FCSR writes are required
  3. Validate regnum ranges in the caller before invoking SetReg

Example fix

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

Strategy: validation

Validate before calling

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

Type guard

func isSettableLOONG64(regNum uint64) bool {
    return (regNum >= regnum.LOONG64_R0 && regNum <= regnum.LOONG64_R0+31) || (regNum >= regnum.LOONG64_F0 && regNum <= regnum.LOONG64_F0+31)
}

Try / catch

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

Prevention

When it happens

Trigger: Calling SetReg on Linux/loong64 with a register number outside the implemented GPR set and outside LOONG64_F0..F0+31 (e.g. FCC, FCSR registers).

Common situations: Attempting to write loong64 floating-point control/status registers; using register constants not defined for this port.

Related errors


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