From bc6e52e4db383f796b5301c906c852298d964539 Mon Sep 17 00:00:00 2001 From: herengui Date: Thu, 31 Aug 2023 11:14:24 +0800 Subject: [PATCH 1000/1001] add loongarch64 support not upstream modified Signed-off-by: herengui --- pkg/proc/bininfo.go | 3 ++ pkg/proc/core/linux_core.go | 54 ++++++++++++++++++++++ pkg/proc/core/minidump/fileflags_string.go | 2 +- pkg/proc/core/minidump/minidump.go | 1 + pkg/proc/native/ptrace_linux_64bit.go | 2 +- pkg/proc/native/support_sentinel.go | 2 +- pkg/proc/pe.go | 2 + pkg/proc/stack.go | 4 +- service/debugger/debugger_test.go | 3 ++ service/debugger/debugger_unix_test.go | 3 ++ 10 files changed, 71 insertions(+), 5 deletions(-) diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 196280f..4d9612b 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -121,6 +121,7 @@ var ( elf.EM_X86_64: true, elf.EM_AARCH64: true, elf.EM_386: true, + elf.EM_LOONGARCH: true, } supportedWindowsArch = map[PEMachine]bool{ @@ -436,6 +437,8 @@ func NewBinaryInfo(goos, goarch string) *BinaryInfo { r.Arch = AMD64Arch(goos) case "arm64": r.Arch = ARM64Arch(goos) + case "loong64": + r.Arch = LOONG64Arch(goos) } return r } diff --git a/pkg/proc/core/linux_core.go b/pkg/proc/core/linux_core.go index 5d758c6..300c67a 100644 --- a/pkg/proc/core/linux_core.go +++ b/pkg/proc/core/linux_core.go @@ -38,6 +38,7 @@ const _NT_FPREGSET elf.NType = 0x2 const ( _EM_AARCH64 = 183 _EM_X86_64 = 62 + _EM_LOONGARCH = 258 _ARM_FP_HEADER_START = 512 ) @@ -47,6 +48,7 @@ func linuxThreadsFromNotes(p *process, notes []*note, machineType elf.Machine) p var currentThread proc.Thread var lastThreadAMD *linuxAMD64Thread var lastThreadARM *linuxARM64Thread + var lastThreadLOONG *linuxLOONG64Thread for _, note := range notes { switch note.Type { case elf.NT_PRSTATUS: @@ -64,12 +66,23 @@ func linuxThreadsFromNotes(p *process, notes []*note, machineType elf.Machine) p if currentThread == nil { currentThread = p.Threads[int(t.Pid)] } + } else if machineType == _EM_LOONGARCH { + t := note.Desc.(*linuxPrStatusLOONG64) + lastThreadLOONG = &linuxLOONG64Thread{linutil.LOONG64Registers{Regs: &t.Reg}, t} + p.Threads[int(t.Pid)] = &thread{lastThreadLOONG, p, proc.CommonThread{}} + if currentThread == nil { + currentThread = p.Threads[int(t.Pid)] + } } case _NT_FPREGSET: if machineType == _EM_AARCH64 { if lastThreadARM != nil { lastThreadARM.regs.Fpregs = note.Desc.(*linutil.ARM64PtraceFpRegs).Decode() } + } else if machineType == _EM_LOONGARCH { + if lastThreadLOONG != nil { + lastThreadLOONG.regs.Fpregs = note.Desc.(*linutil.LOONG64PtraceFpRegs).Decode() + } } case _NT_X86_XSTATE: if machineType == _EM_X86_64 { @@ -129,6 +142,8 @@ func readLinuxCore(corePath, exePath string) (*process, proc.Thread, error) { bi = proc.NewBinaryInfo("linux", "amd64") case _EM_AARCH64: bi = proc.NewBinaryInfo("linux", "arm64") + case _EM_LOONGARCH: + bi = proc.NewBinaryInfo("linux", "loong64") default: return nil, nil, fmt.Errorf("unsupported machine type") } @@ -157,6 +172,11 @@ type linuxARM64Thread struct { t *linuxPrStatusARM64 } +type linuxLOONG64Thread struct { + regs linutil.LOONG64Registers + t *linuxPrStatusLOONG64 +} + func (t *linuxAMD64Thread) registers() (proc.Registers, error) { var r linutil.AMD64Registers r.Regs = t.regs.Regs @@ -171,6 +191,13 @@ func (t *linuxARM64Thread) registers() (proc.Registers, error) { return &r, nil } +func (t *linuxLOONG64Thread) registers() (proc.Registers, error) { + var r linutil.LOONG64Registers + r.Regs = t.regs.Regs + r.Fpregs = t.regs.Fpregs + return &r, nil +} + func (t *linuxAMD64Thread) pid() int { return int(t.t.Pid) } @@ -179,6 +206,10 @@ func (t *linuxARM64Thread) pid() int { return int(t.t.Pid) } +func (t *linuxLOONG64Thread) pid() int { + return int(t.t.Pid) +} + // Note is a note from the PT_NOTE prog. // Relevant types: // - NT_FILE: File mapping information, e.g. program text mappings. Desc is a LinuxNTFile. @@ -250,6 +281,8 @@ func readNote(r io.ReadSeeker, machineType elf.Machine) (*note, error) { note.Desc = &linuxPrStatusAMD64{} } else if machineType == _EM_AARCH64 { note.Desc = &linuxPrStatusARM64{} + } else if machineType == _EM_LOONGARCH { + note.Desc = &linuxPrStatusLOONG64{} } else { return nil, fmt.Errorf("unsupported machine type") } @@ -297,6 +330,14 @@ func readNote(r io.ReadSeeker, machineType elf.Machine) (*note, error) { } note.Desc = fpregs } + if machineType == _EM_LOONGARCH { + fpregs := &linutil.LOONG64PtraceFpRegs{} + rdr := bytes.NewReader(desc) + if err := binary.Read(rdr, binary.LittleEndian, fpregs.Byte()); err != nil { + return nil, err + } + note.Desc = fpregs + } } if err := skipPadding(r, 4); err != nil { return nil, fmt.Errorf("aligning after desc: %v", err) @@ -408,6 +449,19 @@ type linuxPrStatusARM64 struct { Fpvalid int32 } +// LinuxPrStatusLOONG64 is a copy of the prstatus kernel struct. +type linuxPrStatusLOONG64 struct { + Siginfo linuxSiginfo + Cursig uint16 + _ [2]uint8 + Sigpend uint64 + Sighold uint64 + Pid, Ppid, Pgrp, Sid int32 + Utime, Stime, CUtime, CStime linuxCoreTimeval + Reg linutil.LOONG64PtraceRegs + Fpvalid int32 +} + // LinuxSiginfo is a copy of the // siginfo kernel struct. type linuxSiginfo struct { diff --git a/pkg/proc/core/minidump/fileflags_string.go b/pkg/proc/core/minidump/fileflags_string.go index b69969e..54e9c47 100644 --- a/pkg/proc/core/minidump/fileflags_string.go +++ b/pkg/proc/core/minidump/fileflags_string.go @@ -49,7 +49,7 @@ func (i StreamType) String() string { const ( _Arch_name_0 = "CpuArchitectureX86CpuArchitectureMipsCpuArchitectureAlphaCpuArchitecturePPCCpuArchitectureSHXCpuArchitectureARMCpuArchitectureIA64CpuArchitectureAlpha64CpuArchitectureMSILCpuArchitectureAMD64CpuArchitectureWoW64" - _Arch_name_1 = "CpuArchitectureARM64" + _Arch_name_1 = "CpuArchitectureARM64CpuArchitectureLoong64" _Arch_name_2 = "CpuArchitectureUnknown" ) diff --git a/pkg/proc/core/minidump/minidump.go b/pkg/proc/core/minidump/minidump.go index 9348f3c..51f22b8 100644 --- a/pkg/proc/core/minidump/minidump.go +++ b/pkg/proc/core/minidump/minidump.go @@ -313,6 +313,7 @@ const ( CpuArchitectureAMD64 Arch = 9 CpuArchitectureWoW64 Arch = 10 CpuArchitectureARM64 Arch = 12 + CpuArchitectureLoong64 Arch = 13 CpuArchitectureUnknown Arch = 0xffff ) diff --git a/pkg/proc/native/ptrace_linux_64bit.go b/pkg/proc/native/ptrace_linux_64bit.go index d31cdf5..d96bf4b 100644 --- a/pkg/proc/native/ptrace_linux_64bit.go +++ b/pkg/proc/native/ptrace_linux_64bit.go @@ -1,4 +1,4 @@ -// +build linux,amd64 linux,arm64 +// +build linux,amd64 linux,arm64 linux,loong64 package native diff --git a/pkg/proc/native/support_sentinel.go b/pkg/proc/native/support_sentinel.go index d627be9..c54ac1b 100644 --- a/pkg/proc/native/support_sentinel.go +++ b/pkg/proc/native/support_sentinel.go @@ -1,5 +1,5 @@ // This file is used to detect build on unsupported GOOS/GOARCH combinations. -//+build !linux,!darwin,!windows,!freebsd linux,!amd64,!arm64,!386 darwin,!amd64,!arm64 windows,!amd64 freebsd,!amd64 +//+build !linux,!darwin,!windows,!freebsd linux,!amd64,!arm64,!loong64,!386 darwin,!amd64,!arm64 windows,!amd64 freebsd,!amd64 package your_operating_system_and_architecture_combination_is_not_supported_by_delve diff --git a/pkg/proc/pe.go b/pkg/proc/pe.go index 21a9a27..6ee1965 100644 --- a/pkg/proc/pe.go +++ b/pkg/proc/pe.go @@ -14,6 +14,7 @@ const ( IMAGE_FILE_MACHINE_EBC = 0xebc IMAGE_FILE_MACHINE_I386 = 0x14c IMAGE_FILE_MACHINE_IA64 = 0x200 + IMAGE_FILE_MACHINE_LOONGARCH64 = 0x6264 IMAGE_FILE_MACHINE_M32R = 0x9041 IMAGE_FILE_MACHINE_MIPS16 = 0x266 IMAGE_FILE_MACHINE_MIPSFPU = 0x366 @@ -42,6 +43,7 @@ var PEMachineString = map[uint16]string{ IMAGE_FILE_MACHINE_EBC: "ebc", IMAGE_FILE_MACHINE_I386: "i386", IMAGE_FILE_MACHINE_IA64: "ia64", + IMAGE_FILE_MACHINE_LOONGARCH64: "loong64", IMAGE_FILE_MACHINE_M32R: "m32r", IMAGE_FILE_MACHINE_MIPS16: "mips16", IMAGE_FILE_MACHINE_MIPSFPU: "mipsfpu", diff --git a/pkg/proc/stack.go b/pkg/proc/stack.go index 30a306c..2d2d406 100644 --- a/pkg/proc/stack.go +++ b/pkg/proc/stack.go @@ -268,7 +268,7 @@ func (it *stackIterator) switchToGoroutineStack() { it.pc = it.g.PC it.regs.Reg(it.regs.SPRegNum).Uint64Val = it.g.SP it.regs.AddReg(it.regs.BPRegNum, op.DwarfRegisterFromUint64(it.g.BP)) - if it.bi.Arch.Name == "arm64" { + if (it.bi.Arch.Name == "arm64") || (it.bi.Arch.Name == "loong64") { it.regs.Reg(it.regs.LRRegNum).Uint64Val = it.g.LR } } @@ -461,7 +461,7 @@ func (it *stackIterator) advanceRegs() (callFrameRegs op.DwarfRegisters, ret uin } } - if it.bi.Arch.Name == "arm64" { + if (it.bi.Arch.Name == "arm64") || (it.bi.Arch.Name == "loong64") { if ret == 0 && it.regs.Reg(it.regs.LRRegNum) != nil { ret = it.regs.Reg(it.regs.LRRegNum).Uint64Val } diff --git a/service/debugger/debugger_test.go b/service/debugger/debugger_test.go index 275e1a5..a7d0b6b 100644 --- a/service/debugger/debugger_test.go +++ b/service/debugger/debugger_test.go @@ -52,6 +52,9 @@ func TestDebugger_LaunchInvalidFormat(t *testing.T) { if runtime.GOARCH == "arm64" && runtime.GOOS == "linux" { os.Setenv("GOARCH", "amd64") } + if runtime.GOARCH == "loong64" && runtime.GOOS == "linux" { + os.Setenv("GOARCH", "amd64") + } os.Setenv("GOOS", switchOS[runtime.GOOS]) exepath := filepath.Join(buildtestdir, debugname) if err := gobuild.GoBuild(debugname, []string{buildtestdir}, fmt.Sprintf("-o %s", exepath)); err != nil { diff --git a/service/debugger/debugger_unix_test.go b/service/debugger/debugger_unix_test.go index 8592968..703485d 100644 --- a/service/debugger/debugger_unix_test.go +++ b/service/debugger/debugger_unix_test.go @@ -34,6 +34,9 @@ func TestDebugger_LaunchNoExecutablePerm(t *testing.T) { if runtime.GOARCH == "arm64" && runtime.GOOS == "linux" { os.Setenv("GOARCH", "amd64") } + if runtime.GOARCH == "loong64" && runtime.GOOS == "linux" { + os.Setenv("GOARCH", "amd64") + } os.Setenv("GOOS", switchOS[runtime.GOOS]) exepath := filepath.Join(buildtestdir, debugname) defer os.Remove(exepath) -- 2.41.0