gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/hostarch/addr.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package hostarch 16 17 import ( 18 "fmt" 19 ) 20 21 // Addr represents an address in an unspecified address space. 22 // 23 // +stateify savable 24 type Addr uintptr 25 26 // AddLength adds the given length to start and returns the result. ok is true 27 // iff adding the length did not overflow the range of Addr. 28 // 29 // Note: This function is usually used to get the end of an address range 30 // defined by its start address and length. Since the resulting end is 31 // exclusive, end == 0 is technically valid, and corresponds to a range that 32 // extends to the end of the address space, but ok will be false. This isn't 33 // expected to ever come up in practice. 34 func (v Addr) AddLength(length uint64) (end Addr, ok bool) { 35 end = v + Addr(length) 36 // As of this writing (Go 1.21), addrAtLeast64b is required to prevent the 37 // compiler from generating a tautological `length <= MaxUint64` check on 38 // 64-bit architectures. 39 ok = end >= v && (addrAtLeast64b || length <= uint64(^Addr(0))) 40 return 41 } 42 43 // RoundDown is equivalent to function PageRoundDown. 44 func (v Addr) RoundDown() Addr { 45 return PageRoundDown(v) 46 } 47 48 // RoundUp is equivalent to function PageRoundUp. 49 func (v Addr) RoundUp() (Addr, bool) { 50 return PageRoundUp(v) 51 } 52 53 // MustRoundUp is equivalent to function MustPageRoundUp. 54 func (v Addr) MustRoundUp() Addr { 55 return MustPageRoundUp(v) 56 } 57 58 // HugeRoundDown is equivalent to function HugePageRoundDown. 59 func (v Addr) HugeRoundDown() Addr { 60 return HugePageRoundDown(v) 61 } 62 63 // HugeRoundUp is equivalent to function HugePageRoundUp. 64 func (v Addr) HugeRoundUp() (Addr, bool) { 65 return HugePageRoundUp(v) 66 } 67 68 // MustHugeRoundUp is equivalent to function MustHugePageRoundUp. 69 func (v Addr) MustHugeRoundUp() Addr { 70 return MustHugePageRoundUp(v) 71 } 72 73 // PageOffset is equivalent to function PageOffset, except that it casts the 74 // result to uint64. 75 func (v Addr) PageOffset() uint64 { 76 return uint64(PageOffset(v)) 77 } 78 79 // IsPageAligned is equivalent to function IsPageAligned. 80 func (v Addr) IsPageAligned() bool { 81 return IsPageAligned(v) 82 } 83 84 // HugePageOffset is equivalent to function HugePageOffset. 85 func (v Addr) HugePageOffset() uint64 { 86 return uint64(HugePageOffset(v)) 87 } 88 89 // IsHugePageAligned is equivalent to function IsHugePageAligned. 90 func (v Addr) IsHugePageAligned() bool { 91 return IsHugePageAligned(v) 92 } 93 94 // AddrRange is a range of Addrs. 95 // 96 // type AddrRange <generated by go_generics> 97 98 // ToRange returns [v, v+length). 99 func (v Addr) ToRange(length uint64) (AddrRange, bool) { 100 end, ok := v.AddLength(length) 101 return AddrRange{v, end}, ok 102 } 103 104 // IsPageAligned returns true if ar.Start.IsPageAligned() and 105 // ar.End.IsPageAligned(). 106 func (ar AddrRange) IsPageAligned() bool { 107 return ar.Start.IsPageAligned() && ar.End.IsPageAligned() 108 } 109 110 // IsHugePageAligned returns true if ar.Start.IsHugePageAligned() and 111 // ar.End.IsHugePageAligned(). 112 func (ar AddrRange) IsHugePageAligned() bool { 113 return ar.Start.IsHugePageAligned() && ar.End.IsHugePageAligned() 114 } 115 116 // String implements fmt.Stringer.String. 117 func (ar AddrRange) String() string { 118 return fmt.Sprintf("[%#x, %#x)", ar.Start, ar.End) 119 }