diff --git a/unix/linux/mkall.go b/unix/linux/mkall.go index 88d9c82e..d874a353 100644 --- a/unix/linux/mkall.go +++ b/unix/linux/mkall.go @@ -144,12 +144,16 @@ var targets = []target{ } // ptracePairs is a list of pairs of targets that can, in some cases, -// run each other's binaries. -var ptracePairs = []struct{ a1, a2 string }{ - {"386", "amd64"}, - {"arm", "arm64"}, - {"mips", "mips64"}, - {"mipsle", "mips64le"}, +// run each other's binaries. 'archName' is the combined name of 'a1' +// and 'a2', which is used in the file name. Generally we use an 'x' +// suffix in the file name to indicate that the file works for both +// big-endian and little-endian, here we use 'nn' to indicate that this +// file is suitable for 32-bit and 64-bit. +var ptracePairs = []struct{ a1, a2, archName string }{ + {"386", "amd64", "x86"}, + {"arm", "arm64", "armnn"}, + {"mips", "mips64", "mipsnn"}, + {"mipsle", "mips64le", "mipsnnle"}, } func main() { @@ -186,7 +190,7 @@ func main() { fmt.Printf("----- GENERATING ptrace pairs -----\n") ok := true for _, p := range ptracePairs { - if err := generatePtracePair(p.a1, p.a2); err != nil { + if err := generatePtracePair(p.a1, p.a2, p.archName); err != nil { fmt.Printf("%v\n***** FAILURE: %s/%s *****\n\n", err, p.a1, p.a2) ok = false } @@ -545,8 +549,9 @@ func (t *target) mksyscallFlags() (flags []string) { // type for each one. It writes a new file defining the types // PtraceRegsArch1 and PtraceRegsArch2 and the corresponding functions // Ptrace{Get,Set}Regs{arch1,arch2}. This permits debugging the other -// binary on a native system. -func generatePtracePair(arch1, arch2 string) error { +// binary on a native system. 'archName' is the combined name of 'arch1' +// and 'arch2', which is used in the file name. +func generatePtracePair(arch1, arch2, archName string) error { def1, err := ptraceDef(arch1) if err != nil { return err @@ -555,12 +560,12 @@ func generatePtracePair(arch1, arch2 string) error { if err != nil { return err } - f, err := os.Create(fmt.Sprintf("zptrace%s_linux.go", arch1)) + f, err := os.Create(fmt.Sprintf("zptrace_%s_linux.go", archName)) if err != nil { return err } buf := bufio.NewWriter(f) - fmt.Fprintf(buf, "// Code generated by linux/mkall.go generatePtracePair(%s, %s). DO NOT EDIT.\n", arch1, arch2) + fmt.Fprintf(buf, "// Code generated by linux/mkall.go generatePtracePair(%q, %q). DO NOT EDIT.\n", arch1, arch2) fmt.Fprintf(buf, "\n") fmt.Fprintf(buf, "// +build linux\n") fmt.Fprintf(buf, "// +build %s %s\n", arch1, arch2) @@ -572,6 +577,10 @@ func generatePtracePair(arch1, arch2 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 } @@ -617,6 +626,23 @@ 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/zptracearm_linux.go b/unix/zptrace_armnn_linux.go similarity index 61% rename from unix/zptracearm_linux.go rename to unix/zptrace_armnn_linux.go index faf23bbe..8bcde842 100644 --- a/unix/zptracearm_linux.go +++ b/unix/zptrace_armnn_linux.go @@ -1,4 +1,4 @@ -// Code generated by linux/mkall.go generatePtracePair(arm, arm64). DO NOT EDIT. +// Code generated by linux/mkall.go generatePtracePair("arm", "arm64"). DO NOT EDIT. // +build linux // +build arm arm64 @@ -39,3 +39,15 @@ 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/zptracemips_linux.go b/unix/zptrace_mipsnn_linux.go similarity index 93% rename from unix/zptracemips_linux.go rename to unix/zptrace_mipsnn_linux.go index c431131e..24b841ee 100644 --- a/unix/zptracemips_linux.go +++ b/unix/zptrace_mipsnn_linux.go @@ -1,4 +1,4 @@ -// Code generated by linux/mkall.go generatePtracePair(mips, mips64). DO NOT EDIT. +// Code generated by linux/mkall.go generatePtracePair("mips", "mips64"). DO NOT EDIT. // +build linux // +build mips mips64 diff --git a/unix/zptracemipsle_linux.go b/unix/zptrace_mipsnnle_linux.go similarity index 93% rename from unix/zptracemipsle_linux.go rename to unix/zptrace_mipsnnle_linux.go index dc3d6d37..47b04895 100644 --- a/unix/zptracemipsle_linux.go +++ b/unix/zptrace_mipsnnle_linux.go @@ -1,4 +1,4 @@ -// Code generated by linux/mkall.go generatePtracePair(mipsle, mips64le). DO NOT EDIT. +// Code generated by linux/mkall.go generatePtracePair("mipsle", "mips64le"). DO NOT EDIT. // +build linux // +build mipsle mips64le diff --git a/unix/zptrace386_linux.go b/unix/zptrace_x86_linux.go similarity index 95% rename from unix/zptrace386_linux.go rename to unix/zptrace_x86_linux.go index 2d21c49e..ea5d9cb5 100644 --- a/unix/zptrace386_linux.go +++ b/unix/zptrace_x86_linux.go @@ -1,4 +1,4 @@ -// Code generated by linux/mkall.go generatePtracePair(386, amd64). DO NOT EDIT. +// Code generated by linux/mkall.go generatePtracePair("386", "amd64"). DO NOT EDIT. // +build linux // +build 386 amd64