mirror of
https://github.com/golang/sys.git
synced 2026-02-08 19:56:04 +03:00
In Go 1.17 we will introduce a register-based ABI on some platforms, as well as ABI wrappers to bridge the ABIs. For Darwin syscall wrappers, it needs to be called directly, instead of through wrappers. Currently, it is written as that the syscall functions are defined in assembly and their addresses are taken from Go using funcPC. In Go 1.17 this will result in the address of the ABI wrapper, which is undesired. In the syscall package in the standard library we changed to use a compiler intrinsic internal/abi.FuncPCABI0 to take the address of the syscall function. But that is not available to this repo and not available in older versions of Go. Here we take a different approach: taking the address directly from assembly. This also ensures we get the address of the defined syscall function, not the ABI wrapper. Updates golang/go#45702. Change-Id: Ia7480d0fb0ca4fb9bf2f36d2deb1e3e5e4eb8284 Reviewed-on: https://go-review.googlesource.com/c/sys/+/317894 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
87 lines
2.7 KiB
Go
87 lines
2.7 KiB
Go
// Copyright 2018 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.
|
|
|
|
//go:build ignore
|
|
// +build ignore
|
|
|
|
// mkasm_darwin.go generates assembly trampolines to call libSystem routines from Go.
|
|
//This program must be run after mksyscall.go.
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
const ptrsize = 8 // Pointer size. All supported platforms are 64-bit.
|
|
|
|
func writeASMFile(in string, fileName string, buildTags string) {
|
|
trampolines := map[string]bool{}
|
|
|
|
var out bytes.Buffer
|
|
|
|
fmt.Fprintf(&out, "// go run mkasm_darwin.go %s\n", strings.Join(os.Args[1:], " "))
|
|
fmt.Fprintf(&out, "// Code generated by the command above; DO NOT EDIT.\n")
|
|
fmt.Fprintf(&out, "\n")
|
|
fmt.Fprintf(&out, "//go:build %s\n", buildTags)
|
|
fmt.Fprintf(&out, "// +build %s\n", buildTags)
|
|
fmt.Fprintf(&out, "\n")
|
|
fmt.Fprintf(&out, "#include \"textflag.h\"\n")
|
|
for _, line := range strings.Split(in, "\n") {
|
|
const prefix = "var "
|
|
const suffix = "_trampoline_addr uintptr"
|
|
if !strings.HasPrefix(line, prefix) || !strings.HasSuffix(line, suffix) {
|
|
continue
|
|
}
|
|
fn := strings.TrimSuffix(strings.TrimPrefix(line, prefix), suffix)
|
|
if !trampolines[fn] {
|
|
trampolines[fn] = true
|
|
fmt.Fprintf(&out, "\nTEXT %s_trampoline<>(SB),NOSPLIT,$0-0\n", fn)
|
|
fmt.Fprintf(&out, "\tJMP\t%s(SB)\n\n", fn)
|
|
fmt.Fprintf(&out, "GLOBL\t·%s_trampoline_addr(SB), RODATA, $%d\n", fn, ptrsize)
|
|
fmt.Fprintf(&out, "DATA\t·%s_trampoline_addr(SB)/%d, $%s_trampoline<>(SB)\n", fn, ptrsize, fn)
|
|
}
|
|
}
|
|
err := ioutil.WriteFile(fileName, out.Bytes(), 0644)
|
|
if err != nil {
|
|
log.Fatalf("can't write %s: %s", fileName, err)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
in1, err := ioutil.ReadFile("syscall_darwin.go")
|
|
if err != nil {
|
|
log.Fatalf("can't open syscall_darwin.go: %s", err)
|
|
}
|
|
arch := os.Args[1]
|
|
in2, err := ioutil.ReadFile(fmt.Sprintf("syscall_darwin_%s.go", arch))
|
|
if err != nil {
|
|
log.Fatalf("can't open syscall_darwin_%s.go: %s", arch, err)
|
|
}
|
|
in3, err := ioutil.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.go", arch))
|
|
if err != nil {
|
|
log.Fatalf("can't open zsyscall_darwin_%s.go: %s", arch, err)
|
|
}
|
|
in := string(in1) + string(in2) + string(in3)
|
|
|
|
writeASMFile(in, fmt.Sprintf("zsyscall_darwin_%s.s", arch), "go1.12")
|
|
|
|
in1, err = ioutil.ReadFile("syscall_darwin.1_13.go")
|
|
if err != nil {
|
|
log.Fatalf("can't open syscall_darwin.1_13.go: %s", err)
|
|
}
|
|
in2, err = ioutil.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.1_13.go", arch))
|
|
if err != nil {
|
|
log.Fatalf("can't open zsyscall_darwin_%s.1_13.go: %s", arch, err)
|
|
}
|
|
|
|
in = string(in1) + string(in2)
|
|
|
|
writeASMFile(in, fmt.Sprintf("zsyscall_darwin_%s.1_13.s", arch), "go1.13")
|
|
}
|