mremap.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. // Copyright 2023 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build linux || netbsd
  5. package unix
  6. import "unsafe"
  7. type mremapMmapper struct {
  8. mmapper
  9. mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
  10. }
  11. var mapper = &mremapMmapper{
  12. mmapper: mmapper{
  13. active: make(map[*byte][]byte),
  14. mmap: mmap,
  15. munmap: munmap,
  16. },
  17. mremap: mremap,
  18. }
  19. func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
  20. if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&mremapFixed != 0 {
  21. return nil, EINVAL
  22. }
  23. pOld := &oldData[cap(oldData)-1]
  24. m.Lock()
  25. defer m.Unlock()
  26. bOld := m.active[pOld]
  27. if bOld == nil || &bOld[0] != &oldData[0] {
  28. return nil, EINVAL
  29. }
  30. newAddr, errno := m.mremap(uintptr(unsafe.Pointer(&bOld[0])), uintptr(len(bOld)), uintptr(newLength), flags, 0)
  31. if errno != nil {
  32. return nil, errno
  33. }
  34. bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength)
  35. pNew := &bNew[cap(bNew)-1]
  36. if flags&mremapDontunmap == 0 {
  37. delete(m.active, pOld)
  38. }
  39. m.active[pNew] = bNew
  40. return bNew, nil
  41. }
  42. func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
  43. return mapper.Mremap(oldData, newLength, flags)
  44. }