Signed-off-by: herengui <herengui@kylinsec.com.cn> (cherry picked from commit 91b4abdf69d62640a91ec0a081579f4648dc555b)
294 lines
10 KiB
Diff
294 lines
10 KiB
Diff
From bc6e52e4db383f796b5301c906c852298d964539 Mon Sep 17 00:00:00 2001
|
|
From: herengui <herengui@kylinsec.com.cn>
|
|
Date: Thu, 31 Aug 2023 11:14:24 +0800
|
|
Subject: [PATCH 1000/1001] add loongarch64 support not upstream modified
|
|
|
|
Signed-off-by: herengui <herengui@kylinsec.com.cn>
|
|
---
|
|
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
|
|
|