From 8754f64f3b77596dc211dfd830e50de69fc1770f Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Fri, 10 Jun 2022 17:20:54 -0700 Subject: [PATCH] syscall.Getpagesize(): add test, implement for Linux and Windows --- builder/musl.go | 1 + src/os/getpagesize_test.go | 17 ++++++++++++++++ src/os/types_anyos.go | 5 +++++ src/runtime/os_linux.go | 8 ++++++++ src/runtime/os_windows.go | 23 ++++++++++++++++++++++ src/syscall/syscall_libc.go | 8 -------- src/syscall/syscall_libc_darwin.go | 8 ++++++++ src/syscall/syscall_libc_nintendoswitch.go | 4 ++++ src/syscall/syscall_libc_wasi.go | 5 +++++ src/syscall/syscall_nonhosted.go | 6 ++++++ 10 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 src/os/getpagesize_test.go diff --git a/builder/musl.go b/builder/musl.go index fa29496a..5dae0428 100644 --- a/builder/musl.go +++ b/builder/musl.go @@ -115,6 +115,7 @@ var Musl = Library{ "internal/libc.c", "internal/syscall_ret.c", "internal/vdso.c", + "legacy/*.c", "malloc/*.c", "mman/*.c", "signal/*.c", diff --git a/src/os/getpagesize_test.go b/src/os/getpagesize_test.go new file mode 100644 index 00000000..bcba9643 --- /dev/null +++ b/src/os/getpagesize_test.go @@ -0,0 +1,17 @@ +//go:build windows || darwin || (linux && !baremetal) +// +build windows darwin linux,!baremetal + +package os_test + +import ( + "os" + "testing" +) + +func TestGetpagesize(t *testing.T) { + pagesize := os.Getpagesize() + if pagesize == 0x1000 || pagesize == 0x4000 || pagesize == 0x10000 { + return + } + t.Errorf("os.Getpagesize() returns strange value %d", pagesize) +} diff --git a/src/os/types_anyos.go b/src/os/types_anyos.go index bc404f35..e8013cb4 100644 --- a/src/os/types_anyos.go +++ b/src/os/types_anyos.go @@ -7,6 +7,11 @@ package os +import "syscall" + +// Getpagesize returns the underlying system's memory page size. +func Getpagesize() int { return syscall.Getpagesize() } + func (fs *fileStat) Name() string { return fs.name } func (fs *fileStat) IsDir() bool { return fs.Mode().IsDir() } diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go index ba68cb80..2e42515a 100644 --- a/src/runtime/os_linux.go +++ b/src/runtime/os_linux.go @@ -40,3 +40,11 @@ func markGlobals() { start = (start + unsafe.Alignof(uintptr(0)) - 1) &^ (unsafe.Alignof(uintptr(0)) - 1) // align on word boundary markRoots(start, end) } + +//export getpagesize +func libc_getpagesize() int + +//go:linkname syscall_Getpagesize syscall.Getpagesize +func syscall_Getpagesize() int { + return libc_getpagesize() +} diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go index f6ae6864..eb8eea2b 100644 --- a/src/runtime/os_windows.go +++ b/src/runtime/os_windows.go @@ -90,3 +90,26 @@ func markGlobals() { section = (*peSection)(unsafe.Pointer(uintptr(unsafe.Pointer(section)) + unsafe.Sizeof(peSection{}))) } } + +type systeminfo struct { + anon0 [4]byte + dwpagesize uint32 + lpminimumapplicationaddress *byte + lpmaximumapplicationaddress *byte + dwactiveprocessormask uintptr + dwnumberofprocessors uint32 + dwprocessortype uint32 + dwallocationgranularity uint32 + wprocessorlevel uint16 + wprocessorrevision uint16 +} + +//export GetSystemInfo +func _GetSystemInfo(lpSystemInfo unsafe.Pointer) + +//go:linkname syscall_Getpagesize syscall.Getpagesize +func syscall_Getpagesize() int { + var info systeminfo + _GetSystemInfo(unsafe.Pointer(&info)) + return int(info.dwpagesize) +} diff --git a/src/syscall/syscall_libc.go b/src/syscall/syscall_libc.go index 3fa3db04..a02187b5 100644 --- a/src/syscall/syscall_libc.go +++ b/src/syscall/syscall_libc.go @@ -251,10 +251,6 @@ func Mprotect(b []byte, prot int) (err error) { return } -func Getpagesize() int { - return int(libc_getpagesize()) -} - func Environ() []string { // This function combines all the environment into a single allocation. @@ -372,10 +368,6 @@ func libc_munmap(addr unsafe.Pointer, length uintptr) int32 //export mprotect func libc_mprotect(addr unsafe.Pointer, len uintptr, prot int32) int32 -// int getpagesize(); -//export getpagesize -func libc_getpagesize() int32 - // int chdir(const char *pathname, mode_t mode); //export chdir func libc_chdir(pathname *byte) int32 diff --git a/src/syscall/syscall_libc_darwin.go b/src/syscall/syscall_libc_darwin.go index 0342add2..4b1f1716 100644 --- a/src/syscall/syscall_libc_darwin.go +++ b/src/syscall/syscall_libc_darwin.go @@ -267,6 +267,14 @@ func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (err error) { return } +func Getpagesize() int { + return int(libc_getpagesize()) +} + // int pipe(int32 *fds); //export pipe func libc_pipe(fds *int32) int32 + +// int getpagesize(); +//export getpagesize +func libc_getpagesize() int32 diff --git a/src/syscall/syscall_libc_nintendoswitch.go b/src/syscall/syscall_libc_nintendoswitch.go index 52b73939..5b120c93 100644 --- a/src/syscall/syscall_libc_nintendoswitch.go +++ b/src/syscall/syscall_libc_nintendoswitch.go @@ -67,3 +67,7 @@ func getErrno() error { func Pipe2(p []int, flags int) (err error) { return ENOSYS // TODO } + +func Getpagesize() int { + return 4096 // TODO +} diff --git a/src/syscall/syscall_libc_wasi.go b/src/syscall/syscall_libc_wasi.go index cf9da47f..ec9d2304 100644 --- a/src/syscall/syscall_libc_wasi.go +++ b/src/syscall/syscall_libc_wasi.go @@ -296,6 +296,11 @@ func Pipe2(p []int, flags int) (err error) { return ENOSYS // TODO } +func Getpagesize() int { + // per upstream + return 65536 +} + // int stat(const char *path, struct stat * buf); //export stat func libc_stat(pathname *byte, ptr unsafe.Pointer) int32 diff --git a/src/syscall/syscall_nonhosted.go b/src/syscall/syscall_nonhosted.go index 3528087f..399e9742 100644 --- a/src/syscall/syscall_nonhosted.go +++ b/src/syscall/syscall_nonhosted.go @@ -205,3 +205,9 @@ type Timeval struct { Sec int64 Usec int64 } + +func Getpagesize() int { + // There is no right value to return here, but 4096 is a + // common assumption when pagesize is unknown + return 4096 +}