unix: move functions Ptrace{Get|Set}RegSetArm64 to a separate file

CL 204418 adds functions PtraceGetRegSetArm64 and PtraceSetRegSetArm64 to file
zptrace_armnn_linux.go, both of which depend on type Iovec. The definitions of type
Iovec on linux arm and arm64 are different, but file zptrace_armnn_linux.go is
shared by them. So these two functions cause compilation errors on linux arm. This
patch fixes this error by moving these two functions into a separate file.

Fixes golang/go#36032

Change-Id: Ia380bd863895900599c09d4631ed26f204955112
Reviewed-on: https://go-review.googlesource.com/c/sys/+/210322
Run-TryBot: eric fang <eric.fang@arm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/unix/linux/mkall.go b/unix/linux/mkall.go
index d874a35..bb5b773 100644
--- a/unix/linux/mkall.go
+++ b/unix/linux/mkall.go
@@ -195,6 +195,11 @@
 			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 @@
 	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 @@
 	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 8bcde84..89c5920 100644
--- a/unix/zptrace_armnn_linux.go
+++ b/unix/zptrace_armnn_linux.go
@@ -39,15 +39,3 @@
 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 0000000..6cb6d68
--- /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)))
+}