Skip to content

Commit

Permalink
windows: use SyscallN in mkwinsyscall
Browse files Browse the repository at this point in the history
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.

Fixes golang/go#57914

Change-Id: I4205e779a960ae10c0778de7876154e0d7ec00a1
GitHub-Last-Rev: 1f1e96f
GitHub-Pull-Request: #171
Reviewed-on: https://go-review.googlesource.com/c/sys/+/518995
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
  • Loading branch information
mauri870 authored and gopherbot committed Aug 17, 2023
1 parent 7023367 commit ad02017
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 3 deletions.
10 changes: 7 additions & 3 deletions windows/mkwinsyscall/mkwinsyscall.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ import (
"go/parser"
"go/token"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
Expand Down Expand Up @@ -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")
}
Expand All @@ -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)
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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}}
Expand Down
63 changes: 63 additions & 0 deletions windows/mkwinsyscall/mkwinsyscall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"go/format"
"os"
"path/filepath"
"strings"
"testing"
)

Expand Down Expand Up @@ -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())
}
})
}
}

0 comments on commit ad02017

Please sign in to comment.