mirror of
https://github.com/golang/sys.git
synced 2026-01-29 15:12:09 +03:00
x/sys/windows: use SyscallN in mkwinsyscall
The mkwinsyscall command has a hard limit of 15 on the number of syscall arguments. Windows has several system calls with more than 15 arguments, for example CreateFontPackage has 18 arguments. If the number of arguments is higher than 15 we use SyscallN. Updates golang/go#57914
This commit is contained in:
@@ -57,7 +57,6 @@ import (
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -568,6 +567,8 @@ func (f *Fn) SyscallParamCount() int {
|
||||
return 12
|
||||
case n <= 15:
|
||||
return 15
|
||||
case n <= 42: // current SyscallN limit
|
||||
return n
|
||||
default:
|
||||
panic("too many arguments to system call")
|
||||
}
|
||||
@@ -579,6 +580,9 @@ func (f *Fn) Syscall() string {
|
||||
if c == 3 {
|
||||
return syscalldot() + "Syscall"
|
||||
}
|
||||
if c > 15 {
|
||||
return syscalldot() + "SyscallN"
|
||||
}
|
||||
return syscalldot() + "Syscall" + strconv.Itoa(c)
|
||||
}
|
||||
|
||||
@@ -923,7 +927,7 @@ func main() {
|
||||
if *filename == "" {
|
||||
_, err = os.Stdout.Write(data)
|
||||
} else {
|
||||
err = ioutil.WriteFile(*filename, data, 0644)
|
||||
err = os.WriteFile(*filename, data, 0644)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -1011,7 +1015,7 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
|
||||
|
||||
{{define "results"}}{{if .Rets.List}}{{.Rets.List}} {{end}}{{end}}
|
||||
|
||||
{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}}
|
||||
{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(),{{if le .ParamCount 15}} {{.ParamCount}},{{end}} {{.SyscallParamList}}){{end}}
|
||||
|
||||
{{define "tmpvarsreadback"}}{{range .Params}}{{if .TmpVarReadbackCode}}
|
||||
{{.TmpVarReadbackCode}}{{end}}{{end}}{{end}}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"go/format"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -48,3 +49,65 @@ func TestDLLFilenameEscaping(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyscallXGeneration(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
wantsysfunc string
|
||||
sig string
|
||||
}{
|
||||
{
|
||||
name: "syscall with 2 params",
|
||||
wantsysfunc: "syscall.Syscall",
|
||||
sig: "Example(a1 *uint16, a2 *uint16) = ",
|
||||
},
|
||||
{
|
||||
name: "syscall with 6 params",
|
||||
wantsysfunc: "syscall.Syscall6",
|
||||
sig: "Example(a1 *uint, a2 *uint, a3 *uint, a4 *uint, a5 *uint, a6 *uint) = ",
|
||||
},
|
||||
{
|
||||
name: "syscall with 15 params",
|
||||
wantsysfunc: "syscall.Syscall15",
|
||||
sig: strings.ReplaceAll(`Example(a1 *uint, a2 *uint, a3 *uint, a4 *uint, a5 *uint, a6 *uint,
|
||||
a7 *uint, a8 *uint, a9 *uint, a10 *uint, a11 *uint, a12 *uint,
|
||||
a13 *uint, a14 *uint, a15 *uint) = `, "\n", ""),
|
||||
},
|
||||
{
|
||||
name: "syscall with 18 params",
|
||||
wantsysfunc: "syscall.SyscallN",
|
||||
sig: strings.ReplaceAll(`Example(a1 *uint, a2 *uint, a3 *uint, a4 *uint, a5 *uint, a6 *uint,
|
||||
a7 *uint, a8 *uint, a9 *uint, a10 *uint, a11 *uint, a12 *uint,
|
||||
a13 *uint, a14 *uint, a15 *uint, a16 *uint, a17 *uint, a18 *uint) = `, "\n", ""),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Write the syscall into a temp file for testing.
|
||||
prefix := "package windows\n//sys " + tt.sig
|
||||
suffix := ".Example"
|
||||
name := filepath.Join(t.TempDir(), "syscall.go")
|
||||
if err := os.WriteFile(name, []byte(prefix+"example"+suffix), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Ensure parsing, generating, and formatting run without errors.
|
||||
// This is good enough to show that escaping is working.
|
||||
src, err := ParseFiles([]string{name})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := src.Generate(&buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := format.Source(buf.Bytes()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !strings.Contains(buf.String(), tt.wantsysfunc+"(") {
|
||||
t.Fatalf("expected syscall func %q in buffer %s", tt.wantsysfunc, buf.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user