1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build ignore
6
7// mkasm_darwin.go generates assembly trampolines to call libSystem routines from Go.
8//This program must be run after mksyscall.pl.
9package main
10
11import (
12	"bytes"
13	"fmt"
14	"io/ioutil"
15	"log"
16	"os"
17	"strings"
18)
19
20func main() {
21	in1, err := ioutil.ReadFile("syscall_darwin.go")
22	if err != nil {
23		log.Fatalf("can't open syscall_darwin.go: %s", err)
24	}
25	arch := os.Args[1]
26	in2, err := ioutil.ReadFile(fmt.Sprintf("syscall_darwin_%s.go", arch))
27	if err != nil {
28		log.Fatalf("can't open syscall_darwin_%s.go: %s", arch, err)
29	}
30	in3, err := ioutil.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.go", arch))
31	if err != nil {
32		log.Fatalf("can't open zsyscall_darwin_%s.go: %s", arch, err)
33	}
34	in := string(in1) + string(in2) + string(in3)
35
36	trampolines := map[string]bool{}
37
38	var out bytes.Buffer
39
40	fmt.Fprintf(&out, "// go run mkasm_darwin.go %s\n", strings.Join(os.Args[1:], " "))
41	fmt.Fprintf(&out, "// Code generated by the command above; DO NOT EDIT.\n")
42	fmt.Fprintf(&out, "#include \"textflag.h\"\n")
43	for _, line := range strings.Split(in, "\n") {
44		if !strings.HasPrefix(line, "func ") || !strings.HasSuffix(line, "_trampoline()") {
45			continue
46		}
47		fn := line[5 : len(line)-13]
48		if !trampolines[fn] {
49			trampolines[fn] = true
50			fmt.Fprintf(&out, "TEXT ·%s_trampoline(SB),NOSPLIT,$0-0\n", fn)
51			fmt.Fprintf(&out, "\tJMP\t%s(SB)\n", fn)
52		}
53	}
54	err = ioutil.WriteFile(fmt.Sprintf("zsyscall_darwin_%s.s", arch), out.Bytes(), 0644)
55	if err != nil {
56		log.Fatalf("can't write zsyscall_darwin_%s.s: %s", arch, err)
57	}
58}
59