fix(debug): cross-compile for arm64, riscv64 and loong64
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -30,7 +30,7 @@ func (s *Session) Disassemble(addr uint64) (string, int, error) {
|
|||||||
func (s *Session) DisassembleN(addr uint64, n int) string {
|
func (s *Session) DisassembleN(addr uint64, n int) string {
|
||||||
var result string
|
var result string
|
||||||
pc := addr
|
pc := addr
|
||||||
for i := range n {
|
for range n {
|
||||||
text, length, err := s.Disassemble(pc)
|
text, length, err := s.Disassemble(pc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result += fmt.Sprintf(" %#08x: <error: %v>\n", pc, err)
|
result += fmt.Sprintf(" %#08x: <error: %v>\n", pc, err)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func (s *Session) Disassemble(addr uint64) (string, int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "???", 4, nil
|
return "???", 4, nil
|
||||||
}
|
}
|
||||||
text := loong64asm.GoSyntax(inst, addr, nil, nil)
|
text := loong64asm.GoSyntax(inst, addr, nil)
|
||||||
return text, 4, nil
|
return text, 4, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ func (s *Session) Disassemble(addr uint64) (string, int, error) {
|
|||||||
func (s *Session) DisassembleN(addr uint64, n int) string {
|
func (s *Session) DisassembleN(addr uint64, n int) string {
|
||||||
var result string
|
var result string
|
||||||
pc := addr
|
pc := addr
|
||||||
for i := range n {
|
for range n {
|
||||||
text, length, err := s.Disassemble(pc)
|
text, length, err := s.Disassemble(pc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result += fmt.Sprintf(" %#08x: <error: %v>\n", pc, err)
|
result += fmt.Sprintf(" %#08x: <error: %v>\n", pc, err)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func (s *Session) Disassemble(addr uint64) (string, int, error) {
|
|||||||
func (s *Session) DisassembleN(addr uint64, n int) string {
|
func (s *Session) DisassembleN(addr uint64, n int) string {
|
||||||
var result string
|
var result string
|
||||||
pc := addr
|
pc := addr
|
||||||
for i := range n {
|
for range n {
|
||||||
text, length, err := s.Disassemble(pc)
|
text, length, err := s.Disassemble(pc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result += fmt.Sprintf(" %#08x: <error: %v>\n", pc, err)
|
result += fmt.Sprintf(" %#08x: <error: %v>\n", pc, err)
|
||||||
|
|||||||
@@ -44,26 +44,35 @@ func (s *Session) SetRegs(regs *Regs) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FPRegs holds the NEON/FP register state (V0-V31, FPCR, FPSR).
|
// ntPrFPREG is the NT_PRFPREG note type (ELF NT ver): the FP register set.
|
||||||
|
const ntPrFPREG = 0x2
|
||||||
|
|
||||||
|
// FPRegs holds the arm64 FP/NEON register state, matching the kernel's
|
||||||
|
// user_fpsimd_struct layout (32 128-bit V registers, then FPSR and FPCR).
|
||||||
type FPRegs struct {
|
type FPRegs struct {
|
||||||
V [32][16]byte // V0-V31 (128-bit NEON/FP registers)
|
V [32][16]byte // V0-V31 (128-bit NEON/FP registers)
|
||||||
FPCR uint32
|
|
||||||
FPSR uint32
|
FPSR uint32
|
||||||
|
FPCR uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFPRegs retrieves the NEON/FP register state.
|
// GetFPRegs retrieves the FP register state via PTRACE_GETREGSET with
|
||||||
|
// NT_PRFPREG (this architecture has no PTRACE_GETFPREGS request).
|
||||||
func (s *Session) GetFPRegs() (FPRegs, error) {
|
func (s *Session) GetFPRegs() (FPRegs, error) {
|
||||||
var fp FPRegs
|
var fp FPRegs
|
||||||
|
iovec := syscall.Iovec{
|
||||||
|
Base: (*byte)(unsafe.Pointer(&fp)),
|
||||||
|
Len: uint64(unsafe.Sizeof(fp)),
|
||||||
|
}
|
||||||
_, _, errno := syscall.Syscall6(
|
_, _, errno := syscall.Syscall6(
|
||||||
syscall.SYS_PTRACE,
|
syscall.SYS_PTRACE,
|
||||||
uintptr(syscall.PTRACE_GETFPREGS),
|
uintptr(syscall.PTRACE_GETREGSET),
|
||||||
uintptr(s.pid),
|
uintptr(s.pid),
|
||||||
0,
|
uintptr(ntPrFPREG),
|
||||||
uintptr(unsafe.Pointer(&fp)),
|
uintptr(unsafe.Pointer(&iovec)),
|
||||||
0, 0,
|
0, 0,
|
||||||
)
|
)
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
return fp, fmt.Errorf("debug: PTRACE_GETFPREGS: %w", errno)
|
return fp, fmt.Errorf("debug: PTRACE_GETREGSET (NT_PRFPREG): %w", errno)
|
||||||
}
|
}
|
||||||
return fp, nil
|
return fp, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,25 +44,36 @@ func (s *Session) SetRegs(regs *Regs) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FPRegs holds the LoongArch FP register state (F0-F31).
|
// ntPrFPREG is the NT_PRFPREG note type (ELF NT ver): the FP register set.
|
||||||
|
const ntPrFPREG = 0x2
|
||||||
|
|
||||||
|
// FPRegs holds the LoongArch FP register state, matching the kernel's
|
||||||
|
// user_fp_struct layout (32 64-bit FP registers, the fcc condition flags,
|
||||||
|
// and fcsr).
|
||||||
type FPRegs struct {
|
type FPRegs struct {
|
||||||
F [32][16]byte // F0-F31 (128-bit, lower 64 bits used for double)
|
F [32]uint64 // F0-F31 (64-bit FP registers)
|
||||||
|
FCC uint64 // eight per-register condition flags, packed
|
||||||
FCSR uint32
|
FCSR uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFPRegs retrieves the FP register state.
|
// GetFPRegs retrieves the FP register state via PTRACE_GETREGSET with
|
||||||
|
// NT_PRFPREG (this architecture has no PTRACE_GETFPREGS request).
|
||||||
func (s *Session) GetFPRegs() (FPRegs, error) {
|
func (s *Session) GetFPRegs() (FPRegs, error) {
|
||||||
var fp FPRegs
|
var fp FPRegs
|
||||||
|
iovec := syscall.Iovec{
|
||||||
|
Base: (*byte)(unsafe.Pointer(&fp)),
|
||||||
|
Len: uint64(unsafe.Sizeof(fp)),
|
||||||
|
}
|
||||||
_, _, errno := syscall.Syscall6(
|
_, _, errno := syscall.Syscall6(
|
||||||
syscall.SYS_PTRACE,
|
syscall.SYS_PTRACE,
|
||||||
uintptr(syscall.PTRACE_GETFPREGS),
|
uintptr(syscall.PTRACE_GETREGSET),
|
||||||
uintptr(s.pid),
|
uintptr(s.pid),
|
||||||
0,
|
uintptr(ntPrFPREG),
|
||||||
uintptr(unsafe.Pointer(&fp)),
|
uintptr(unsafe.Pointer(&iovec)),
|
||||||
0, 0,
|
0, 0,
|
||||||
)
|
)
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
return fp, fmt.Errorf("debug: PTRACE_GETFPREGS: %w", errno)
|
return fp, fmt.Errorf("debug: PTRACE_GETREGSET (NT_PRFPREG): %w", errno)
|
||||||
}
|
}
|
||||||
return fp, nil
|
return fp, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,25 +44,34 @@ func (s *Session) SetRegs(regs *Regs) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FPRegs holds the RISC-V FP register state (F0-F31).
|
// ntPrFPREG is the NT_PRFPREG note type (ELF NT ver): the FP register set.
|
||||||
|
const ntPrFPREG = 0x2
|
||||||
|
|
||||||
|
// FPRegs holds the RISC-V FP register state, matching the kernel's
|
||||||
|
// user_fp_struct layout (32 64-bit FP registers plus fcsr).
|
||||||
type FPRegs struct {
|
type FPRegs struct {
|
||||||
F [32][16]byte // F0-F31 (128-bit, lower 64 bits used for double)
|
F [32]uint64 // F0-F31 (64-bit FP registers)
|
||||||
FCSR uint32
|
FCSR uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFPRegs retrieves the FP register state.
|
// GetFPRegs retrieves the FP register state via PTRACE_GETREGSET with
|
||||||
|
// NT_PRFPREG (this architecture has no PTRACE_GETFPREGS request).
|
||||||
func (s *Session) GetFPRegs() (FPRegs, error) {
|
func (s *Session) GetFPRegs() (FPRegs, error) {
|
||||||
var fp FPRegs
|
var fp FPRegs
|
||||||
|
iovec := syscall.Iovec{
|
||||||
|
Base: (*byte)(unsafe.Pointer(&fp)),
|
||||||
|
Len: uint64(unsafe.Sizeof(fp)),
|
||||||
|
}
|
||||||
_, _, errno := syscall.Syscall6(
|
_, _, errno := syscall.Syscall6(
|
||||||
syscall.SYS_PTRACE,
|
syscall.SYS_PTRACE,
|
||||||
uintptr(syscall.PTRACE_GETFPREGS),
|
uintptr(syscall.PTRACE_GETREGSET),
|
||||||
uintptr(s.pid),
|
uintptr(s.pid),
|
||||||
0,
|
uintptr(ntPrFPREG),
|
||||||
uintptr(unsafe.Pointer(&fp)),
|
uintptr(unsafe.Pointer(&iovec)),
|
||||||
0, 0,
|
0, 0,
|
||||||
)
|
)
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
return fp, fmt.Errorf("debug: PTRACE_GETFPREGS: %w", errno)
|
return fp, fmt.Errorf("debug: PTRACE_GETREGSET (NT_PRFPREG): %w", errno)
|
||||||
}
|
}
|
||||||
return fp, nil
|
return fp, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func RunTarget(asmPath, funcName, argsFile, tmpDir string) error {
|
|||||||
|
|
||||||
bufSpecFile := tmpDir + "/bufspec"
|
bufSpecFile := tmpDir + "/bufspec"
|
||||||
if bufSpec, err := os.ReadFile(bufSpecFile); err == nil && len(bufSpec) > 0 {
|
if bufSpec, err := os.ReadFile(bufSpecFile); err == nil && len(bufSpec) > 0 {
|
||||||
args, err = setupBuffers(string(bufSpec), args, fl.Args, tmpDir)
|
args, err = setupBuffers(string(bufSpec), args, tmpDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("debug target: setup buffers: %w", err)
|
return fmt.Errorf("debug target: setup buffers: %w", err)
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ func RunTarget(asmPath, funcName, argsFile, tmpDir string) error {
|
|||||||
stackArgs := make([]byte, fl.Args)
|
stackArgs := make([]byte, fl.Args)
|
||||||
copy(stackArgs, args)
|
copy(stackArgs, args)
|
||||||
|
|
||||||
_, callErr := verify.Call(stackArgs)
|
_, callErr := verify.Call(fnAddr, stackArgs)
|
||||||
if callErr != nil {
|
if callErr != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func RunTarget(asmPath, funcName, argsFile, tmpDir string) error {
|
|||||||
stackArgs := make([]byte, fl.Args)
|
stackArgs := make([]byte, fl.Args)
|
||||||
copy(stackArgs, args)
|
copy(stackArgs, args)
|
||||||
|
|
||||||
_, callErr := verify.Call(stackArgs)
|
_, callErr := verify.Call(fnAddr, stackArgs)
|
||||||
if callErr != nil {
|
if callErr != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,7 @@ func RunTarget(asmPath, funcName, argsFile, tmpDir string) error {
|
|||||||
return fmt.Errorf("debug target: parse: %v", errs[0])
|
return fmt.Errorf("debug target: parse: %v", errs[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
var img *asm.Image
|
img, err := asm.AssembleFileRISCV(file)
|
||||||
switch "riscv64" {
|
|
||||||
case "arm64":
|
|
||||||
img, err = asm.AssembleFileARM64(file)
|
|
||||||
case "riscv64":
|
|
||||||
img, err = asm.AssembleFileRISCV(file)
|
|
||||||
case "loong64":
|
|
||||||
img, err = asm.AssembleFileLOONG64(file)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("debug target: assemble: %w", err)
|
return fmt.Errorf("debug target: assemble: %w", err)
|
||||||
}
|
}
|
||||||
@@ -107,7 +99,7 @@ func RunTarget(asmPath, funcName, argsFile, tmpDir string) error {
|
|||||||
stackArgs := make([]byte, fl.Args)
|
stackArgs := make([]byte, fl.Args)
|
||||||
copy(stackArgs, args)
|
copy(stackArgs, args)
|
||||||
|
|
||||||
_, callErr := verify.Call(stackArgs)
|
_, callErr := verify.Call(fnAddr, stackArgs)
|
||||||
if callErr != nil {
|
if callErr != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ func (s *Session) getHWBreakState() (*hwBreakState, error) {
|
|||||||
var state hwBreakState
|
var state hwBreakState
|
||||||
iovec := syscall.Iovec{
|
iovec := syscall.Iovec{
|
||||||
Base: (*byte)(unsafe.Pointer(&state)),
|
Base: (*byte)(unsafe.Pointer(&state)),
|
||||||
Len: uint32(unsafe.Sizeof(state)),
|
Len: uint64(unsafe.Sizeof(state)),
|
||||||
}
|
}
|
||||||
_, _, errno := syscall.Syscall6(
|
_, _, errno := syscall.Syscall6(
|
||||||
syscall.SYS_PTRACE,
|
syscall.SYS_PTRACE,
|
||||||
@@ -164,7 +164,7 @@ func (s *Session) getHWBreakState() (*hwBreakState, error) {
|
|||||||
func (s *Session) setHWBreakState(state *hwBreakState) error {
|
func (s *Session) setHWBreakState(state *hwBreakState) error {
|
||||||
iovec := syscall.Iovec{
|
iovec := syscall.Iovec{
|
||||||
Base: (*byte)(unsafe.Pointer(state)),
|
Base: (*byte)(unsafe.Pointer(state)),
|
||||||
Len: uint32(unsafe.Sizeof(*state)),
|
Len: uint64(unsafe.Sizeof(*state)),
|
||||||
}
|
}
|
||||||
_, _, errno := syscall.Syscall6(
|
_, _, errno := syscall.Syscall6(
|
||||||
syscall.SYS_PTRACE,
|
syscall.SYS_PTRACE,
|
||||||
|
|||||||
Reference in New Issue
Block a user