summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/sys/unix/linux/mkall.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/sys/unix/linux/mkall.go')
-rw-r--r--vendor/golang.org/x/sys/unix/linux/mkall.go103
1 files changed, 103 insertions, 0 deletions
diff --git a/vendor/golang.org/x/sys/unix/linux/mkall.go b/vendor/golang.org/x/sys/unix/linux/mkall.go
index 429754f16..89b2fe886 100644
--- a/vendor/golang.org/x/sys/unix/linux/mkall.go
+++ b/vendor/golang.org/x/sys/unix/linux/mkall.go
@@ -15,12 +15,17 @@
package main
import (
+ "bufio"
+ "bytes"
"fmt"
+ "io"
+ "io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
+ "unicode"
)
// These will be paths to the appropriate source directories.
@@ -128,6 +133,15 @@ 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"},
+}
+
func main() {
if runtime.GOOS != GOOS || runtime.GOARCH != BuildArch {
fmt.Printf("Build system has GOOS_GOARCH = %s_%s, need %s_%s\n",
@@ -158,6 +172,18 @@ func main() {
fmt.Printf("----- SUCCESS: %s -----\n\n", t.GoArch)
}
}
+
+ fmt.Printf("----- GENERATING ptrace pairs -----\n")
+ ok := true
+ for _, p := range ptracePairs {
+ if err := generatePtracePair(p.a1, p.a2); err != nil {
+ fmt.Printf("%v\n***** FAILURE: %s/%s *****\n\n", err, p.a1, p.a2)
+ ok = false
+ }
+ }
+ if ok {
+ fmt.Printf("----- SUCCESS ptrace pairs -----\n\n")
+ }
}
// Makes an exec.Cmd with Stderr attached to os.Stderr
@@ -377,3 +403,80 @@ func (t *target) mksyscallFlags() (flags []string) {
}
return
}
+
+// generatePtracePair takes a pair of GOARCH values that can run each
+// other's binaries, such as 386 and amd64. It extracts the PtraceRegs
+// 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 {
+ def1, err := ptraceDef(arch1)
+ if err != nil {
+ return err
+ }
+ def2, err := ptraceDef(arch2)
+ if err != nil {
+ return err
+ }
+ f, err := os.Create(fmt.Sprintf("zptrace%s_linux.go", arch1))
+ 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, "\n")
+ fmt.Fprintf(buf, "// +build linux\n")
+ fmt.Fprintf(buf, "// +build %s %s\n", arch1, arch2)
+ 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")
+ writeOnePtrace(buf, arch1, def1)
+ fmt.Fprintf(buf, "\n")
+ writeOnePtrace(buf, arch2, def2)
+ if err := buf.Flush(); err != nil {
+ return err
+ }
+ if err := f.Close(); err != nil {
+ return err
+ }
+ return nil
+}
+
+// ptraceDef returns the definition of PtraceRegs for arch.
+func ptraceDef(arch string) (string, error) {
+ filename := fmt.Sprintf("ztypes_linux_%s.go", arch)
+ data, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return "", fmt.Errorf("reading %s: %v", filename, err)
+ }
+ start := bytes.Index(data, []byte("type PtraceRegs struct"))
+ if start < 0 {
+ return "", fmt.Errorf("%s: no definition of PtraceRegs", filename)
+ }
+ data = data[start:]
+ end := bytes.Index(data, []byte("\n}\n"))
+ if end < 0 {
+ return "", fmt.Errorf("%s: can't find end of PtraceRegs definition", filename)
+ }
+ return string(data[:end+2]), nil
+}
+
+// writeOnePtrace writes out the ptrace definitions for arch.
+func writeOnePtrace(w io.Writer, arch, def string) {
+ uarch := string(unicode.ToUpper(rune(arch[0]))) + arch[1:]
+ fmt.Fprintf(w, "// PtraceRegs%s is the registers used by %s binaries.\n", uarch, arch)
+ fmt.Fprintf(w, "%s\n", strings.Replace(def, "PtraceRegs", "PtraceRegs"+uarch, 1))
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintf(w, "// PtraceGetRegs%s fetches the registers used by %s binaries.\n", uarch, arch)
+ fmt.Fprintf(w, "func PtraceGetRegs%s(pid int, regsout *PtraceRegs%s) error {\n", uarch, uarch)
+ fmt.Fprintf(w, "\treturn ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))\n")
+ fmt.Fprintf(w, "}\n")
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintf(w, "// PtraceSetRegs%s sets the registers used by %s binaries.\n", uarch, arch)
+ fmt.Fprintf(w, "func PtraceSetRegs%s(pid int, regs *PtraceRegs%s) error {\n", uarch, uarch)
+ fmt.Fprintf(w, "\treturn ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))\n")
+ fmt.Fprintf(w, "}\n")
+}