github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/pprof/vminfo_darwin.go (about) 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 5 package pprof 6 7 import ( 8 "os" 9 "unsafe" 10 ) 11 12 func isExecutable(protection int32) bool { 13 return (protection&_VM_PROT_EXECUTE) != 0 && (protection&_VM_PROT_READ) != 0 14 } 15 16 // machVMInfo uses the mach_vm_region region system call to add mapping entries 17 // for the text region of the running process. 18 func machVMInfo(addMapping func(lo, hi, offset uint64, file, buildID string)) bool { 19 added := false 20 var addr uint64 = 0x1 21 for { 22 var memRegionSize uint64 23 var info machVMRegionBasicInfoData 24 // Get the first address and page size. 25 kr := mach_vm_region( 26 &addr, 27 &memRegionSize, 28 unsafe.Pointer(&info)) 29 if kr != 0 { 30 if kr == _MACH_SEND_INVALID_DEST { 31 // No more memory regions. 32 return true 33 } 34 return added // return true if at least one mapping was added 35 } 36 if isExecutable(info.Protection) { 37 // NOTE: the meaning/value of Offset is unclear. However, 38 // this likely doesn't matter as the text segment's file 39 // offset is usually 0. 40 addMapping(addr, 41 addr+memRegionSize, 42 read64(&info.Offset), 43 regionFilename(addr), 44 "") 45 added = true 46 } 47 addr += memRegionSize 48 } 49 } 50 51 func read64(p *[8]byte) uint64 { 52 // all supported darwin platforms are little endian 53 return uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 54 } 55 56 func regionFilename(address uint64) string { 57 buf := make([]byte, _MAXPATHLEN) 58 r := proc_regionfilename( 59 os.Getpid(), 60 address, 61 unsafe.SliceData(buf), 62 int64(cap(buf))) 63 if r == 0 { 64 return "" 65 } 66 return string(buf[:r]) 67 } 68 69 // mach_vm_region and proc_regionfilename are implemented by 70 // the runtime package (runtime/sys_darwin.go). 71 // 72 //go:noescape 73 func mach_vm_region(address, region_size *uint64, info unsafe.Pointer) int32 74 75 //go:noescape 76 func proc_regionfilename(pid int, address uint64, buf *byte, buflen int64) int32