mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-06 00:57:18 -04:00
unix: add Mremap for linux
For golang/go#60409 Change-Id: I75a9732ee996f0aeb91599d80803f96ada468c27 GitHub-Last-Rev: c348b6194d9fbe92f4f912c66709b0af75810e99 GitHub-Pull-Request: golang/sys#164 Reviewed-on: https://go-review.googlesource.com/c/sys/+/502715 Auto-Submit: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Run-TryBot: Ian Lance Taylor <iant@google.com>
This commit is contained in:
committed by
Gopher Robot
parent
ca096e46e8
commit
e0c3b6e6ae
+1
-1
@@ -519,7 +519,7 @@ ccflags="$@"
|
|||||||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
|
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
|
||||||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
|
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
|
||||||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
|
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
|
||||||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
|
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
|
||||||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
|
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
|
||||||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
|
$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
|
||||||
$2 ~ /^RAW_PAYLOAD_/ ||
|
$2 ~ /^RAW_PAYLOAD_/ ||
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2023 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 linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
type mremapMmapper struct {
|
||||||
|
mmapper
|
||||||
|
mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
|
||||||
|
if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&MREMAP_FIXED != 0 {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
pOld := &oldData[cap(oldData)-1]
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
bOld := m.active[pOld]
|
||||||
|
if bOld == nil || &bOld[0] != &oldData[0] {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
newAddr, errno := m.mremap(uintptr(unsafe.Pointer(&bOld[0])), uintptr(len(bOld)), uintptr(newLength), flags, 0)
|
||||||
|
if errno != nil {
|
||||||
|
return nil, errno
|
||||||
|
}
|
||||||
|
bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength)
|
||||||
|
pNew := &bNew[cap(bNew)-1]
|
||||||
|
if flags&MREMAP_DONTUNMAP == 0 {
|
||||||
|
delete(m.active, pOld)
|
||||||
|
}
|
||||||
|
m.active[pNew] = bNew
|
||||||
|
return bNew, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2023 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 linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package unix_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMremap(t *testing.T) {
|
||||||
|
b, err := unix.Mmap(-1, 0, unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Mmap: %v", err)
|
||||||
|
}
|
||||||
|
if err := unix.Mprotect(b, unix.PROT_READ|unix.PROT_WRITE); err != nil {
|
||||||
|
t.Fatalf("Mprotect: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b[0] = 42
|
||||||
|
|
||||||
|
bNew, err := unix.Mremap(b, unix.Getpagesize()*2, unix.MREMAP_MAYMOVE)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Mremap2: %v", err)
|
||||||
|
}
|
||||||
|
bNew[unix.Getpagesize()+1] = 84 // checks
|
||||||
|
|
||||||
|
if bNew[0] != 42 {
|
||||||
|
t.Fatal("first element value was changed")
|
||||||
|
}
|
||||||
|
if len(bNew) != unix.Getpagesize()*2 {
|
||||||
|
t.Fatal("new memory len not equal to specified len")
|
||||||
|
}
|
||||||
|
if cap(bNew) != unix.Getpagesize()*2 {
|
||||||
|
t.Fatal("new memory cap not equal to specified len")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = unix.Mremap(b, unix.Getpagesize(), unix.MREMAP_FIXED)
|
||||||
|
if err != unix.EINVAL {
|
||||||
|
t.Fatalf("unix.MREMAP_FIXED should be forbidden")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2124,11 +2124,15 @@ func writevRacedetect(iovecs []Iovec, n int) {
|
|||||||
|
|
||||||
// mmap varies by architecture; see syscall_linux_*.go.
|
// mmap varies by architecture; see syscall_linux_*.go.
|
||||||
//sys munmap(addr uintptr, length uintptr) (err error)
|
//sys munmap(addr uintptr, length uintptr) (err error)
|
||||||
|
//sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
|
||||||
|
|
||||||
var mapper = &mmapper{
|
var mapper = &mremapMmapper{
|
||||||
|
mmapper: mmapper{
|
||||||
active: make(map[*byte][]byte),
|
active: make(map[*byte][]byte),
|
||||||
mmap: mmap,
|
mmap: mmap,
|
||||||
munmap: munmap,
|
munmap: munmap,
|
||||||
|
},
|
||||||
|
mremap: mremap,
|
||||||
}
|
}
|
||||||
|
|
||||||
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
||||||
@@ -2139,6 +2143,10 @@ func Munmap(b []byte) (err error) {
|
|||||||
return mapper.Munmap(b)
|
return mapper.Munmap(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
|
||||||
|
return mapper.Mremap(oldData, newLength, flags)
|
||||||
|
}
|
||||||
|
|
||||||
//sys Madvise(b []byte, advice int) (err error)
|
//sys Madvise(b []byte, advice int) (err error)
|
||||||
//sys Mprotect(b []byte, prot int) (err error)
|
//sys Mprotect(b []byte, prot int) (err error)
|
||||||
//sys Mlock(b []byte) (err error)
|
//sys Mlock(b []byte) (err error)
|
||||||
@@ -2487,7 +2495,6 @@ func Getresgid() (rgid, egid, sgid int) {
|
|||||||
// MqTimedreceive
|
// MqTimedreceive
|
||||||
// MqTimedsend
|
// MqTimedsend
|
||||||
// MqUnlink
|
// MqUnlink
|
||||||
// Mremap
|
|
||||||
// Msgctl
|
// Msgctl
|
||||||
// Msgget
|
// Msgget
|
||||||
// Msgrcv
|
// Msgrcv
|
||||||
|
|||||||
@@ -1904,6 +1904,9 @@ const (
|
|||||||
MOUNT_ATTR_SIZE_VER0 = 0x20
|
MOUNT_ATTR_SIZE_VER0 = 0x20
|
||||||
MOUNT_ATTR_STRICTATIME = 0x20
|
MOUNT_ATTR_STRICTATIME = 0x20
|
||||||
MOUNT_ATTR__ATIME = 0x70
|
MOUNT_ATTR__ATIME = 0x70
|
||||||
|
MREMAP_DONTUNMAP = 0x4
|
||||||
|
MREMAP_FIXED = 0x2
|
||||||
|
MREMAP_MAYMOVE = 0x1
|
||||||
MSDOS_SUPER_MAGIC = 0x4d44
|
MSDOS_SUPER_MAGIC = 0x4d44
|
||||||
MSG_BATCH = 0x40000
|
MSG_BATCH = 0x40000
|
||||||
MSG_CMSG_CLOEXEC = 0x40000000
|
MSG_CMSG_CLOEXEC = 0x40000000
|
||||||
|
|||||||
@@ -1868,6 +1868,17 @@ func munmap(addr uintptr, length uintptr) (err error) {
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) {
|
||||||
|
r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldaddr), uintptr(oldlength), uintptr(newlength), uintptr(flags), uintptr(newaddr), 0)
|
||||||
|
xaddr = uintptr(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Madvise(b []byte, advice int) (err error) {
|
func Madvise(b []byte, advice int) (err error) {
|
||||||
var _p0 unsafe.Pointer
|
var _p0 unsafe.Pointer
|
||||||
if len(b) > 0 {
|
if len(b) > 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user