diff --git a/unix/linux/mkall.go b/unix/linux/mkall.go index d874a353..bb5b773c 100644 --- a/unix/linux/mkall.go +++ b/unix/linux/mkall.go @@ -195,6 +195,11 @@ func main() { ok = false } } + // generate functions PtraceGetRegSetArm64 and PtraceSetRegSetArm64. + if err := generatePtraceRegSet("arm64"); err != nil { + fmt.Printf("%v\n***** FAILURE: generatePtraceRegSet(%q) *****\n\n", err, "arm64") + ok = false + } if ok { fmt.Printf("----- SUCCESS ptrace pairs -----\n\n") } @@ -577,10 +582,41 @@ func generatePtracePair(arch1, arch2, archName string) error { writeOnePtrace(buf, arch1, def1) fmt.Fprintf(buf, "\n") writeOnePtrace(buf, arch2, def2) - if arch2 == "arm64" { - fmt.Fprintf(buf, "\n") - writeOnePtraceRegSet(buf, arch2) + if err := buf.Flush(); err != nil { + return err } + if err := f.Close(); err != nil { + return err + } + return nil +} + +// generatePtraceRegSet takes a GOARCH value to generate a file zptrace_linux_{arch}.go +// containing functions PtraceGetRegSet{arch} and PtraceSetRegSet{arch}. +func generatePtraceRegSet(arch string) error { + f, err := os.Create(fmt.Sprintf("zptrace_linux_%s.go", arch)) + if err != nil { + return err + } + buf := bufio.NewWriter(f) + fmt.Fprintf(buf, "// Code generated by linux/mkall.go generatePtraceRegSet(%q). DO NOT EDIT.\n", arch) + fmt.Fprintf(buf, "\n") + fmt.Fprintf(buf, "package unix\n") + fmt.Fprintf(buf, "\n") + fmt.Fprintf(buf, "%s\n", `import "unsafe"`) + fmt.Fprintf(buf, "\n") + uarch := string(unicode.ToUpper(rune(arch[0]))) + arch[1:] + fmt.Fprintf(buf, "// PtraceGetRegSet%s fetches the registers used by %s binaries.\n", uarch, arch) + fmt.Fprintf(buf, "func PtraceGetRegSet%s(pid, addr int, regsout *PtraceRegs%s) error {\n", uarch, uarch) + fmt.Fprintf(buf, "\tiovec := Iovec{(*byte)(unsafe.Pointer(regsout)), uint64(unsafe.Sizeof(*regsout))}\n") + fmt.Fprintf(buf, "\treturn ptrace(PTRACE_GETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec)))\n") + fmt.Fprintf(buf, "}\n") + fmt.Fprintf(buf, "\n") + fmt.Fprintf(buf, "// PtraceSetRegSet%s sets the registers used by %s binaries.\n", uarch, arch) + fmt.Fprintf(buf, "func PtraceSetRegSet%s(pid, addr int, regs *PtraceRegs%s) error {\n", uarch, uarch) + fmt.Fprintf(buf, "\tiovec := Iovec{(*byte)(unsafe.Pointer(regs)), uint64(unsafe.Sizeof(*regs))}\n") + fmt.Fprintf(buf, "\treturn ptrace(PTRACE_SETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec)))\n") + fmt.Fprintf(buf, "}\n") if err := buf.Flush(); err != nil { return err } @@ -626,23 +662,6 @@ func writeOnePtrace(w io.Writer, arch, def string) { fmt.Fprintf(w, "}\n") } -// writeOnePtraceRegSet writes out the ptrace definitions of PTRACE_GETREGSET and -// PTRACE_SETREGSET request type. -func writeOnePtraceRegSet(w io.Writer, arch string) { - uarch := string(unicode.ToUpper(rune(arch[0]))) + arch[1:] - fmt.Fprintf(w, "// PtraceGetRegSet%s fetches the registers used by %s binaries.\n", uarch, arch) - fmt.Fprintf(w, "func PtraceGetRegSet%s(pid, addr int, regsout *PtraceRegs%s) error {\n", uarch, uarch) - fmt.Fprintf(w, "\tiovec := Iovec{(*byte)(unsafe.Pointer(regsout)), uint64(unsafe.Sizeof(*regsout))}\n") - fmt.Fprintf(w, "\treturn ptrace(PTRACE_GETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec)))\n") - fmt.Fprintf(w, "}\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, "// PtraceSetRegSet%s sets the registers used by %s binaries.\n", uarch, arch) - fmt.Fprintf(w, "func PtraceSetRegSet%s(pid, addr int, regs *PtraceRegs%s) error {\n", uarch, uarch) - fmt.Fprintf(w, "\tiovec := Iovec{(*byte)(unsafe.Pointer(regs)), uint64(unsafe.Sizeof(*regs))}\n") - fmt.Fprintf(w, "\treturn ptrace(PTRACE_SETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec)))\n") - fmt.Fprintf(w, "}\n") -} - // cCode is compiled for the target architecture, and the resulting data section is carved for // the statically initialized bit masks. const cCode = ` diff --git a/unix/zptrace_armnn_linux.go b/unix/zptrace_armnn_linux.go index 8bcde842..89c5920e 100644 --- a/unix/zptrace_armnn_linux.go +++ b/unix/zptrace_armnn_linux.go @@ -39,15 +39,3 @@ func PtraceGetRegsArm64(pid int, regsout *PtraceRegsArm64) error { func PtraceSetRegsArm64(pid int, regs *PtraceRegsArm64) error { return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) } - -// PtraceGetRegSetArm64 fetches the registers used by arm64 binaries. -func PtraceGetRegSetArm64(pid, addr int, regsout *PtraceRegsArm64) error { - iovec := Iovec{(*byte)(unsafe.Pointer(regsout)), uint64(unsafe.Sizeof(*regsout))} - return ptrace(PTRACE_GETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec))) -} - -// PtraceSetRegSetArm64 sets the registers used by arm64 binaries. -func PtraceSetRegSetArm64(pid, addr int, regs *PtraceRegsArm64) error { - iovec := Iovec{(*byte)(unsafe.Pointer(regs)), uint64(unsafe.Sizeof(*regs))} - return ptrace(PTRACE_SETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec))) -} diff --git a/unix/zptrace_linux_arm64.go b/unix/zptrace_linux_arm64.go new file mode 100644 index 00000000..6cb6d688 --- /dev/null +++ b/unix/zptrace_linux_arm64.go @@ -0,0 +1,17 @@ +// Code generated by linux/mkall.go generatePtraceRegSet("arm64"). DO NOT EDIT. + +package unix + +import "unsafe" + +// PtraceGetRegSetArm64 fetches the registers used by arm64 binaries. +func PtraceGetRegSetArm64(pid, addr int, regsout *PtraceRegsArm64) error { + iovec := Iovec{(*byte)(unsafe.Pointer(regsout)), uint64(unsafe.Sizeof(*regsout))} + return ptrace(PTRACE_GETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec))) +} + +// PtraceSetRegSetArm64 sets the registers used by arm64 binaries. +func PtraceSetRegSetArm64(pid, addr int, regs *PtraceRegsArm64) error { + iovec := Iovec{(*byte)(unsafe.Pointer(regs)), uint64(unsafe.Sizeof(*regs))} + return ptrace(PTRACE_SETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec))) +}