// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// linux/mkall.go - Generates all Linux zsysnum, zsyscall, zerror, and ztype
// files for all Linux architectures supported by the go compiler. See
// README.md for more information about the build system.

// To run it you must have a git checkout of the Linux kernel and glibc. Once
// the appropriate sources are ready, the program is run as:
//     go run linux/mkall.go <linux_dir> <glibc_dir>

//go:build ignore
// +build ignore

package main

import (
	"bufio"
	"bytes"
	"debug/elf"
	"encoding/binary"
	"errors"
	"fmt"
	"go/build/constraint"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"unicode"
)

// These will be paths to the appropriate source directories.
var LinuxDir string
var GlibcDir string

const TempDir = "/tmp"

const GOOS = "linux"       // Only for Linux targets
const BuildArch = "amd64"  // Must be built on this architecture
const MinKernel = "2.6.23" // https://golang.org/doc/install#requirements

type target struct {
	GoArch     string // Architecture name according to Go
	LinuxArch  string // Architecture name according to the Linux Kernel
	GNUArch    string // Architecture name according to GNU tools (https://wiki.debian.org/Multiarch/Tuples)
	BigEndian  bool   // Default Little Endian
	SignedChar bool   // Is -fsigned-char needed (default no)
	Bits       int
	env        []string
	stderrBuf  bytes.Buffer
	compiler   string
}

// List of all Linux targets supported by the go compiler. Currently, sparc64 is
// not fully supported, but there is enough support already to generate Go type
// and error definitions.
var targets = []target{
	{
		GoArch:    "386",
		LinuxArch: "x86",
		GNUArch:   "i686-linux-gnu", // Note "i686" not "i386"
		Bits:      32,
	},
	{
		GoArch:    "amd64",
		LinuxArch: "x86",
		GNUArch:   "x86_64-linux-gnu",
		Bits:      64,
	},
	{
		GoArch:     "arm64",
		LinuxArch:  "arm64",
		GNUArch:    "aarch64-linux-gnu",
		SignedChar: true,
		Bits:       64,
	},
	{
		GoArch:    "arm",
		LinuxArch: "arm",
		GNUArch:   "arm-linux-gnueabi",
		Bits:      32,
	},
	{
		GoArch:    "loong64",
		LinuxArch: "loongarch",
		GNUArch:   "loongarch64-linux-gnu",
		Bits:      64,
	},
	{
		GoArch:    "mips",
		LinuxArch: "mips",
		GNUArch:   "mips-linux-gnu",
		BigEndian: true,
		Bits:      32,
	},
	{
		GoArch:    "mipsle",
		LinuxArch: "mips",
		GNUArch:   "mipsel-linux-gnu",
		Bits:      32,
	},
	{
		GoArch:    "mips64",
		LinuxArch: "mips",
		GNUArch:   "mips64-linux-gnuabi64",
		BigEndian: true,
		Bits:      64,
	},
	{
		GoArch:    "mips64le",
		LinuxArch: "mips",
		GNUArch:   "mips64el-linux-gnuabi64",
		Bits:      64,
	},
	{
		GoArch:    "ppc",
		LinuxArch: "powerpc",
		GNUArch:   "powerpc-linux-gnu",
		BigEndian: true,
		Bits:      32,
	},
	{
		GoArch:    "ppc64",
		LinuxArch: "powerpc",
		GNUArch:   "powerpc64-linux-gnu",
		BigEndian: true,
		Bits:      64,
	},
	{
		GoArch:    "ppc64le",
		LinuxArch: "powerpc",
		GNUArch:   "powerpc64le-linux-gnu",
		Bits:      64,
	},
	{
		GoArch:    "riscv64",
		LinuxArch: "riscv",
		GNUArch:   "riscv64-linux-gnu",
		Bits:      64,
	},
	{
		GoArch:     "s390x",
		LinuxArch:  "s390",
		GNUArch:    "s390x-linux-gnu",
		BigEndian:  true,
		SignedChar: true,
		Bits:       64,
	},
	{
		GoArch:    "sparc64",
		LinuxArch: "sparc",
		GNUArch:   "sparc64-linux-gnu",
		BigEndian: true,
		Bits:      64,
	},
}

// ptracePairs is a list of pairs of targets that can, in some cases,
// 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() {
	if runtime.GOOS != GOOS || runtime.GOARCH != BuildArch {
		fmt.Printf("Build system has GOOS_GOARCH = %s_%s, need %s_%s\n",
			runtime.GOOS, runtime.GOARCH, GOOS, BuildArch)
		return
	}

	// Check that we are using the new build system if we should
	if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
		fmt.Println("In the new build system, mkall.go should not be called directly.")
		fmt.Println("See README.md")
		return
	}

	// Parse the command line options
	if len(os.Args) != 3 {
		fmt.Println("USAGE: go run linux/mkall.go <linux_dir> <glibc_dir>")
		return
	}
	LinuxDir = os.Args[1]
	GlibcDir = os.Args[2]

	wg := sync.WaitGroup{}
	for _, t := range targets {
		fmt.Printf("arch %s: GENERATING\n", t.GoArch)
		if err := t.setupEnvironment(); err != nil {
			fmt.Printf("arch %s: could not setup environment: %v\n", t.GoArch, err)
			break
		}
		includeDir := filepath.Join(TempDir, t.GoArch, "include")
		// Make the include directory and fill it with headers
		if err := os.MkdirAll(includeDir, os.ModePerm); err != nil {
			fmt.Printf("arch %s: could not make directory: %v\n", t.GoArch, err)
			break
		}
		// During header generation "/git/linux/scripts/basic/fixdep" is created by "basic/Makefile" for each
		// instance of "make headers_install". This leads to a "text file is busy" error from any running
		// "make headers_install" after the first one's target. Workaround is to serialize header generation
		if err := t.makeHeaders(); err != nil {
			fmt.Printf("arch %s: could not make header files: %v\n", t.GoArch, err)
			break
		}
		wg.Add(1)
		go func(t target) {
			defer wg.Done()
			fmt.Printf("arch %s: header files generated\n", t.GoArch)
			if err := t.generateFiles(); err != nil {
				fmt.Printf("%v\n***** FAILURE:    %s *****\n\n", err, t.GoArch)
			} else {
				fmt.Printf("arch %s: SUCCESS\n", t.GoArch)
			}
		}(t)
	}
	wg.Wait()

	fmt.Printf("----- GENERATING: merging generated files -----\n")
	if err := mergeFiles(); err != nil {
		fmt.Printf("%v\n***** FAILURE:    merging generated files *****\n\n", err)
	} else {
		fmt.Printf("----- SUCCESS:    merging generated files -----\n\n")
	}

	fmt.Printf("----- GENERATING ptrace pairs -----\n")
	ok := true
	for _, p := range ptracePairs {
		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
		}
	}
	// 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")
	}
}

func (t *target) printAndResetBuilder() {
	if t.stderrBuf.Len() > 0 {
		for _, l := range bytes.Split(t.stderrBuf.Bytes(), []byte{'\n'}) {
			fmt.Printf("arch %s: stderr: %s\n", t.GoArch, l)
		}
		t.stderrBuf.Reset()
	}
}

// Makes an exec.Cmd with Stderr attached to the target string Builder, and target environment
func (t *target) makeCommand(name string, args ...string) *exec.Cmd {
	cmd := exec.Command(name, args...)
	cmd.Env = t.env
	cmd.Stderr = &t.stderrBuf
	return cmd
}

// Set GOARCH for target and build environments.
func (t *target) setTargetBuildArch(cmd *exec.Cmd) {
	// Set GOARCH_TARGET so command knows what GOARCH is..
	var env []string
	env = append(env, t.env...)
	cmd.Env = append(env, "GOARCH_TARGET="+t.GoArch)
	// Set GOARCH to host arch for command, so it can run natively.
	for i, s := range cmd.Env {
		if strings.HasPrefix(s, "GOARCH=") {
			cmd.Env[i] = "GOARCH=" + BuildArch
		}
	}
}

// Runs the command, pipes output to a formatter, pipes that to an output file.
func (t *target) commandFormatOutput(formatter string, outputFile string,
	name string, args ...string) (err error) {
	mainCmd := t.makeCommand(name, args...)
	if name == "mksyscall" {
		args = append([]string{"run", "mksyscall.go"}, args...)
		mainCmd = t.makeCommand("go", args...)
		t.setTargetBuildArch(mainCmd)
	} else if name == "mksysnum" {
		args = append([]string{"run", "linux/mksysnum.go"}, args...)
		mainCmd = t.makeCommand("go", args...)
		t.setTargetBuildArch(mainCmd)
	}

	fmtCmd := t.makeCommand(formatter)
	if formatter == "mkpost" {
		fmtCmd = t.makeCommand("go", "run", "mkpost.go")
		t.setTargetBuildArch(fmtCmd)
	} else if formatter == "gofmt2" {
		fmtCmd = t.makeCommand("gofmt")
		mainCmd.Dir = filepath.Join(TempDir, t.GoArch, "mkerrors")
		if err = os.MkdirAll(mainCmd.Dir, os.ModePerm); err != nil {
			return err
		}
	}

	defer t.printAndResetBuilder()

	// mainCmd | fmtCmd > outputFile
	if fmtCmd.Stdin, err = mainCmd.StdoutPipe(); err != nil {
		return
	}
	if fmtCmd.Stdout, err = os.Create(outputFile); err != nil {
		return
	}

	// Make sure the formatter eventually closes
	if err = fmtCmd.Start(); err != nil {
		return
	}
	defer func() {
		fmtErr := fmtCmd.Wait()
		if err == nil {
			err = fmtErr
		}
	}()

	return mainCmd.Run()
}

func (t *target) setupEnvironment() error {
	// Setup environment variables
	t.env = append(os.Environ(), fmt.Sprintf("%s=%s", "GOOS", GOOS))
	t.env = append(t.env, fmt.Sprintf("%s=%s", "GOARCH", t.GoArch))

	// Get appropriate compiler and emulator (unless on x86)
	if t.LinuxArch != "x86" {
		// Check/Setup cross compiler
		t.compiler = t.GNUArch + "-gcc"
		if _, err := exec.LookPath(t.compiler); err != nil {
			return err
		}
		t.env = append(t.env, fmt.Sprintf("%s=%s", "CC", t.compiler))

		// Check/Setup emulator (usually first component of GNUArch)
		qemuArchName := t.GNUArch[:strings.Index(t.GNUArch, "-")]
		if t.LinuxArch == "powerpc" {
			qemuArchName = t.GoArch
		}
		// Fake uname for QEMU to allow running on Host kernel version < 4.15
		if t.LinuxArch == "riscv" {
			t.env = append(t.env, fmt.Sprintf("%s=%s", "QEMU_UNAME", "4.15"))
		}
		t.env = append(t.env, fmt.Sprintf("%s=%s", "GORUN", "qemu-"+qemuArchName))
	} else {
		t.compiler = "gcc"
		t.env = append(t.env, fmt.Sprintf("%s=%s", "CC", "gcc"))
	}
	return nil
}

// Generates all the files for a Linux target
func (t *target) generateFiles() error {
	// Make each of the four files
	if err := t.makeZSysnumFile(); err != nil {
		return fmt.Errorf("could not make zsysnum file: %v", err)
	}
	fmt.Printf("arch %s: zsysnum file generated\n", t.GoArch)

	if err := t.makeZSyscallFile(); err != nil {
		return fmt.Errorf("could not make zsyscall file: %v", err)
	}
	fmt.Printf("arch %s: zsyscall file generated\n", t.GoArch)

	if err := t.makeZTypesFile(); err != nil {
		return fmt.Errorf("could not make ztypes file: %v", err)
	}
	fmt.Printf("arch %s: ztypes file generated\n", t.GoArch)

	if err := t.makeZErrorsFile(); err != nil {
		return fmt.Errorf("could not make zerrors file: %v", err)
	}
	fmt.Printf("arch %s: zerrors file generated\n", t.GoArch)

	return nil
}

// Create the Linux, glibc and ABI (C compiler convention) headers in the include directory.
func (t *target) makeHeaders() error {
	defer t.printAndResetBuilder()

	// Make the Linux headers we need for this architecture
	linuxMake := t.makeCommand("make", "headers_install", "ARCH="+t.LinuxArch, "INSTALL_HDR_PATH="+filepath.Join(TempDir, t.GoArch))
	linuxMake.Dir = LinuxDir
	if err := linuxMake.Run(); err != nil {
		return err
	}

	buildDir := filepath.Join(TempDir, t.GoArch, "build")
	// A Temporary build directory for glibc
	if err := os.MkdirAll(buildDir, os.ModePerm); err != nil {
		return err
	}
	defer os.RemoveAll(buildDir)

	// Make the glibc headers we need for this architecture
	confScript := filepath.Join(GlibcDir, "configure")
	glibcArgs := []string{"--prefix=" + filepath.Join(TempDir, t.GoArch), "--host=" + t.GNUArch}
	if t.LinuxArch == "loongarch" {
		// The minimum version requirement of the Loongarch for the kernel in glibc
		// is 5.19, if --enable-kernel is less than 5.19, glibc handles errors
		glibcArgs = append(glibcArgs, "--enable-kernel=5.19.0")
	} else {
		glibcArgs = append(glibcArgs, "--enable-kernel="+MinKernel)
	}
	glibcConf := t.makeCommand(confScript, glibcArgs...)

	glibcConf.Dir = buildDir
	if err := glibcConf.Run(); err != nil {
		return err
	}
	glibcMake := t.makeCommand("make", "install-headers")
	glibcMake.Dir = buildDir
	if err := glibcMake.Run(); err != nil {
		return err
	}
	// We only need an empty stubs file
	stubsFile := filepath.Join(TempDir, t.GoArch, "include", "gnu", "stubs.h")
	if file, err := os.Create(stubsFile); err != nil {
		return err
	} else {
		file.Close()
	}

	// ABI headers will specify C compiler behavior for the target platform.
	return t.makeABIHeaders()
}

// makeABIHeaders generates C header files based on the platform's calling convention.
// While many platforms have formal Application Binary Interfaces, in practice, whatever the
// dominant C compilers generate is the de-facto calling convention.
//
// We generate C headers instead of a Go file, so as to enable references to the ABI from Cgo.
func (t *target) makeABIHeaders() (err error) {
	abiDir := filepath.Join(TempDir, t.GoArch, "include", "abi")
	if err = os.Mkdir(abiDir, os.ModePerm); err != nil {
		return err
	}

	if t.compiler == "" {
		return errors.New("CC (compiler) env var not set")
	}

	// Build a sacrificial ELF file, to mine for C compiler behavior.
	binPath := filepath.Join(TempDir, t.GoArch, "tmp_abi.o")
	bin, err := t.buildELF(t.compiler, cCode, binPath)
	if err != nil {
		return fmt.Errorf("cannot build ELF to analyze: %v", err)
	}
	defer bin.Close()
	defer os.Remove(binPath)

	// Right now, we put everything in abi.h, but we may change this later.
	abiFile, err := os.Create(filepath.Join(abiDir, "abi.h"))
	if err != nil {
		return err
	}
	defer func() {
		if cerr := abiFile.Close(); cerr != nil && err == nil {
			err = cerr
		}
	}()

	if err = t.writeBitFieldMasks(bin, abiFile); err != nil {
		return fmt.Errorf("cannot write bitfield masks: %v", err)
	}

	return nil
}

func (t *target) buildELF(cc, src, path string) (*elf.File, error) {
	// Compile the cCode source using the set compiler - we will need its .data section.
	// Do not link the binary, so that we can find .data section offsets from the symbol values.
	ccCmd := t.makeCommand(cc, "-o", path, "-gdwarf", "-x", "c", "-c", "-")
	ccCmd.Stdin = strings.NewReader(src)
	ccCmd.Stdout = os.Stdout
	defer t.printAndResetBuilder()
	if err := ccCmd.Run(); err != nil {
		return nil, fmt.Errorf("compiler error: %v", err)
	}

	bin, err := elf.Open(path)
	if err != nil {
		return nil, fmt.Errorf("cannot read ELF file %s: %v", path, err)
	}

	return bin, nil
}

func (t *target) writeBitFieldMasks(bin *elf.File, out io.Writer) error {
	symbols, err := bin.Symbols()
	if err != nil {
		return fmt.Errorf("getting ELF symbols: %v", err)
	}
	var masksSym *elf.Symbol

	for _, sym := range symbols {
		if sym.Name == "masks" {
			masksSym = &sym
		}
	}

	if masksSym == nil {
		return errors.New("could not find the 'masks' symbol in ELF symtab")
	}

	dataSection := bin.Section(".data")
	if dataSection == nil {
		return errors.New("ELF file has no .data section")
	}

	data, err := dataSection.Data()
	if err != nil {
		return fmt.Errorf("could not read .data section: %v\n", err)
	}

	var bo binary.ByteOrder
	if t.BigEndian {
		bo = binary.BigEndian
	} else {
		bo = binary.LittleEndian
	}

	// 64 bit masks of type uint64 are stored in the data section starting at masks.Value.
	// Here we are running on AMD64, but these values may be big endian or little endian,
	// depending on target architecture.
	for i := uint64(0); i < 64; i++ {
		off := masksSym.Value + i*8
		// Define each mask in native by order, so as to match target endian.
		fmt.Fprintf(out, "#define BITFIELD_MASK_%d %dULL\n", i, bo.Uint64(data[off:off+8]))
	}

	return nil
}

// makes the zsysnum_linux_$GOARCH.go file
func (t *target) makeZSysnumFile() error {
	zsysnumFile := fmt.Sprintf("zsysnum_linux_%s.go", t.GoArch)
	unistdFile := filepath.Join(TempDir, t.GoArch, "include", "asm", "unistd.h")

	args := append(t.cFlags(), unistdFile)
	return t.commandFormatOutput("gofmt", zsysnumFile, "mksysnum", args...)
}

// makes the zsyscall_linux_$GOARCH.go file
func (t *target) makeZSyscallFile() error {
	zsyscallFile := fmt.Sprintf("zsyscall_linux_%s.go", t.GoArch)
	// Find the correct architecture syscall file (might end with x.go)
	archSyscallFile := fmt.Sprintf("syscall_linux_%s.go", t.GoArch)
	if _, err := os.Stat(archSyscallFile); os.IsNotExist(err) {
		shortArch := strings.TrimSuffix(t.GoArch, "le")
		archSyscallFile = fmt.Sprintf("syscall_linux_%sx.go", shortArch)
	}

	args := append(t.mksyscallFlags(), "-tags", "linux,"+t.GoArch,
		"syscall_linux.go",
		archSyscallFile,
	)

	files, err := t.archMksyscallFiles()
	if err != nil {
		return fmt.Errorf("failed to check GOARCH-specific mksyscall files: %v", err)
	}
	args = append(args, files...)

	return t.commandFormatOutput("gofmt", zsyscallFile, "mksyscall", args...)
}

// archMksyscallFiles produces additional file arguments to mksyscall if the
// build constraints in those files match those defined for target.
func (t *target) archMksyscallFiles() ([]string, error) {
	// These input files don't fit the typical GOOS/GOARCH file name conventions
	// but are included conditionally in the arguments to mksyscall based on
	// whether or not the target matches the build constraints defined in each
	// file.
	//
	// TODO(mdlayher): it should be possible to generalize this approach to work
	// over all of syscall_linux_* rather than hard-coding a few special files.
	// Investigate this.
	inputs := []string{
		// GOARCH: all except arm* and riscv.
		"syscall_linux_alarm.go",
	}

	var outputs []string
	for _, in := range inputs {
		ok, err := t.matchesMksyscallFile(in)
		if err != nil {
			return nil, fmt.Errorf("failed to parse file %q: %v", in, err)
		}
		if ok {
			// Constraints match, use for this target's code generation.
			outputs = append(outputs, in)
		}
	}

	return outputs, nil
}

// matchesMksyscallFile reports whether the input file contains constraints
// which match those defined for target.
func (t *target) matchesMksyscallFile(file string) (bool, error) {
	f, err := os.Open(file)
	if err != nil {
		return false, err
	}
	defer f.Close()

	var (
		expr  constraint.Expr
		found bool
	)

	s := bufio.NewScanner(f)
	for s.Scan() {
		// Keep scanning until a valid constraint is found or we hit EOF.
		//
		// This only supports single-line constraints such as the //go:build
		// convention used in Go 1.17+. Because the old //+build convention
		// (which may have multiple lines of build tags) is being deprecated,
		// we don't bother looking for multi-line constraints.
		if expr, err = constraint.Parse(s.Text()); err == nil {
			found = true
			break
		}
	}
	if err := s.Err(); err != nil {
		return false, err
	}
	if !found {
		return false, errors.New("no build constraints found")
	}

	// Do the defined constraints match target's GOOS/GOARCH?
	ok := expr.Eval(func(tag string) bool {
		return tag == GOOS || tag == t.GoArch
	})

	return ok, nil
}

// makes the zerrors_linux_$GOARCH.go file
func (t *target) makeZErrorsFile() error {
	zerrorsFile := fmt.Sprintf("zerrors_linux_%s.go", t.GoArch)
	return t.commandFormatOutput("gofmt2", zerrorsFile, "/"+filepath.Join("build", "unix", "mkerrors.sh"), t.cFlags()...)
}

// makes the ztypes_linux_$GOARCH.go file
func (t *target) makeZTypesFile() error {
	ztypesFile := fmt.Sprintf("ztypes_linux_%s.go", t.GoArch)

	cgoDir := filepath.Join(TempDir, t.GoArch, "cgo")
	if err := os.MkdirAll(cgoDir, os.ModePerm); err != nil {
		return err
	}

	args := []string{"tool", "cgo", "-godefs", "-objdir=" + cgoDir, "--"}
	args = append(args, t.cFlags()...)
	args = append(args, "linux/types.go")
	return t.commandFormatOutput("mkpost", ztypesFile, "go", args...)
}

// Flags that should be given to gcc and cgo for this target
func (t *target) cFlags() []string {
	// Compile statically to avoid cross-architecture dynamic linking.
	flags := []string{"-Wall", "-Werror", "-static", "-I" + filepath.Join(TempDir, t.GoArch, "include")}

	// Architecture-specific flags
	if t.SignedChar {
		flags = append(flags, "-fsigned-char")
	}
	if t.LinuxArch == "x86" {
		flags = append(flags, fmt.Sprintf("-m%d", t.Bits))
	}

	return flags
}

// Flags that should be given to mksyscall for this target
func (t *target) mksyscallFlags() (flags []string) {
	if t.Bits == 32 {
		if t.BigEndian {
			flags = append(flags, "-b32")
		} else {
			flags = append(flags, "-l32")
		}
	}

	// This flag means a 64-bit value should use (even, odd)-pair.
	if t.GoArch == "arm" || (t.LinuxArch == "mips" && t.Bits == 32) {
		flags = append(flags, "-arm")
	}
	return
}

// Merge all the generated files for Linux targets
func mergeFiles() error {
	// Setup environment variables
	os.Setenv("GOOS", runtime.GOOS)
	os.Setenv("GOARCH", runtime.GOARCH)

	// Merge each of the four type of files
	for _, ztyp := range []string{"zerrors", "zsyscall", "zsysnum", "ztypes"} {
		cmd := exec.Command("go", "run", "./internal/mkmerge", "-out", fmt.Sprintf("%s_%s.go", ztyp, GOOS), fmt.Sprintf("%s_%s_*.go", ztyp, GOOS))
		cmd.Stderr = os.Stderr
		err := cmd.Run()
		if err != nil {
			return fmt.Errorf("could not merge %s files: %w", ztyp, err)
		}
		fmt.Printf("%s files merged\n", ztyp)
	}

	return nil
}

// 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. '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
	}
	def2, err := ptraceDef(arch2)
	if err != nil {
		return err
	}
	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(%q, %q). DO NOT EDIT.\n", arch1, arch2)
	fmt.Fprintf(buf, "\n")
	fmt.Fprintf(buf, "//go:build linux && (%s || %s)\n", arch1, arch2)
	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
}

// 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 ptracePtr(PTRACE_GETREGSET, pid, uintptr(addr), 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 ptracePtr(PTRACE_SETREGSET, pid, uintptr(addr), unsafe.Pointer(&iovec))\n")
	fmt.Fprintf(buf, "}\n")
	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 := os.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 ptracePtr(PTRACE_GETREGS, pid, 0, 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 ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs))\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 = `
// Bit fields are used in some system calls and other ABIs, but their memory layout is
// implementation-defined [1]. Even with formal ABIs, bit fields are a source of subtle bugs [2].
// Here we generate the offsets for all 64 bits in an uint64.
// 1: http://en.cppreference.com/w/c/language/bit_field
// 2: https://lwn.net/Articles/478657/

#include <stdint.h>

struct bitfield {
	union {
		uint64_t val;
		struct {
			uint64_t u64_bit_0 : 1;
			uint64_t u64_bit_1 : 1;
			uint64_t u64_bit_2 : 1;
			uint64_t u64_bit_3 : 1;
			uint64_t u64_bit_4 : 1;
			uint64_t u64_bit_5 : 1;
			uint64_t u64_bit_6 : 1;
			uint64_t u64_bit_7 : 1;
			uint64_t u64_bit_8 : 1;
			uint64_t u64_bit_9 : 1;
			uint64_t u64_bit_10 : 1;
			uint64_t u64_bit_11 : 1;
			uint64_t u64_bit_12 : 1;
			uint64_t u64_bit_13 : 1;
			uint64_t u64_bit_14 : 1;
			uint64_t u64_bit_15 : 1;
			uint64_t u64_bit_16 : 1;
			uint64_t u64_bit_17 : 1;
			uint64_t u64_bit_18 : 1;
			uint64_t u64_bit_19 : 1;
			uint64_t u64_bit_20 : 1;
			uint64_t u64_bit_21 : 1;
			uint64_t u64_bit_22 : 1;
			uint64_t u64_bit_23 : 1;
			uint64_t u64_bit_24 : 1;
			uint64_t u64_bit_25 : 1;
			uint64_t u64_bit_26 : 1;
			uint64_t u64_bit_27 : 1;
			uint64_t u64_bit_28 : 1;
			uint64_t u64_bit_29 : 1;
			uint64_t u64_bit_30 : 1;
			uint64_t u64_bit_31 : 1;
			uint64_t u64_bit_32 : 1;
			uint64_t u64_bit_33 : 1;
			uint64_t u64_bit_34 : 1;
			uint64_t u64_bit_35 : 1;
			uint64_t u64_bit_36 : 1;
			uint64_t u64_bit_37 : 1;
			uint64_t u64_bit_38 : 1;
			uint64_t u64_bit_39 : 1;
			uint64_t u64_bit_40 : 1;
			uint64_t u64_bit_41 : 1;
			uint64_t u64_bit_42 : 1;
			uint64_t u64_bit_43 : 1;
			uint64_t u64_bit_44 : 1;
			uint64_t u64_bit_45 : 1;
			uint64_t u64_bit_46 : 1;
			uint64_t u64_bit_47 : 1;
			uint64_t u64_bit_48 : 1;
			uint64_t u64_bit_49 : 1;
			uint64_t u64_bit_50 : 1;
			uint64_t u64_bit_51 : 1;
			uint64_t u64_bit_52 : 1;
			uint64_t u64_bit_53 : 1;
			uint64_t u64_bit_54 : 1;
			uint64_t u64_bit_55 : 1;
			uint64_t u64_bit_56 : 1;
			uint64_t u64_bit_57 : 1;
			uint64_t u64_bit_58 : 1;
			uint64_t u64_bit_59 : 1;
			uint64_t u64_bit_60 : 1;
			uint64_t u64_bit_61 : 1;
			uint64_t u64_bit_62 : 1;
			uint64_t u64_bit_63 : 1;
		};
	};
};

struct bitfield masks[] = {
	{.u64_bit_0 = 1},
	{.u64_bit_1 = 1},
	{.u64_bit_2 = 1},
	{.u64_bit_3 = 1},
	{.u64_bit_4 = 1},
	{.u64_bit_5 = 1},
	{.u64_bit_6 = 1},
	{.u64_bit_7 = 1},
	{.u64_bit_8 = 1},
	{.u64_bit_9 = 1},
	{.u64_bit_10 = 1},
	{.u64_bit_11 = 1},
	{.u64_bit_12 = 1},
	{.u64_bit_13 = 1},
	{.u64_bit_14 = 1},
	{.u64_bit_15 = 1},
	{.u64_bit_16 = 1},
	{.u64_bit_17 = 1},
	{.u64_bit_18 = 1},
	{.u64_bit_19 = 1},
	{.u64_bit_20 = 1},
	{.u64_bit_21 = 1},
	{.u64_bit_22 = 1},
	{.u64_bit_23 = 1},
	{.u64_bit_24 = 1},
	{.u64_bit_25 = 1},
	{.u64_bit_26 = 1},
	{.u64_bit_27 = 1},
	{.u64_bit_28 = 1},
	{.u64_bit_29 = 1},
	{.u64_bit_30 = 1},
	{.u64_bit_31 = 1},
	{.u64_bit_32 = 1},
	{.u64_bit_33 = 1},
	{.u64_bit_34 = 1},
	{.u64_bit_35 = 1},
	{.u64_bit_36 = 1},
	{.u64_bit_37 = 1},
	{.u64_bit_38 = 1},
	{.u64_bit_39 = 1},
	{.u64_bit_40 = 1},
	{.u64_bit_41 = 1},
	{.u64_bit_42 = 1},
	{.u64_bit_43 = 1},
	{.u64_bit_44 = 1},
	{.u64_bit_45 = 1},
	{.u64_bit_46 = 1},
	{.u64_bit_47 = 1},
	{.u64_bit_48 = 1},
	{.u64_bit_49 = 1},
	{.u64_bit_50 = 1},
	{.u64_bit_51 = 1},
	{.u64_bit_52 = 1},
	{.u64_bit_53 = 1},
	{.u64_bit_54 = 1},
	{.u64_bit_55 = 1},
	{.u64_bit_56 = 1},
	{.u64_bit_57 = 1},
	{.u64_bit_58 = 1},
	{.u64_bit_59 = 1},
	{.u64_bit_60 = 1},
	{.u64_bit_61 = 1},
	{.u64_bit_62 = 1},
	{.u64_bit_63 = 1}
};

int main(int argc, char **argv) {
	struct bitfield *mask_ptr = &masks[0];
	return mask_ptr->val;
}

`
