github.com/ttpreport/gvisor-ligolo@v0.0.0-20240123134145-a858404967ba/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  	// The second half of the following check is needed in case uintptr is
    37  	// smaller than 64 bits.
    38  	ok = end >= v && length <= uint64(^Addr(0))
    39  	return
    40  }
    41  
    42  // RoundDown is equivalent to function PageRoundDown.
    43  func (v Addr) RoundDown() Addr {
    44  	return PageRoundDown(v)
    45  }
    46  
    47  // RoundUp is equivalent to function PageRoundUp.
    48  func (v Addr) RoundUp() (Addr, bool) {
    49  	return PageRoundUp(v)
    50  }
    51  
    52  // MustRoundUp is equivalent to function MustPageRoundUp.
    53  func (v Addr) MustRoundUp() Addr {
    54  	return MustPageRoundUp(v)
    55  }
    56  
    57  // HugeRoundDown is equivalent to function HugePageRoundDown.
    58  func (v Addr) HugeRoundDown() Addr {
    59  	return HugePageRoundDown(v)
    60  }
    61  
    62  // HugeRoundUp is equivalent to function HugePageRoundUp.
    63  func (v Addr) HugeRoundUp() (Addr, bool) {
    64  	return HugePageRoundUp(v)
    65  }
    66  
    67  // PageOffset is equivalent to function PageOffset, except that it casts the
    68  // result to uint64.
    69  func (v Addr) PageOffset() uint64 {
    70  	return uint64(PageOffset(v))
    71  }
    72  
    73  // IsPageAligned is equivalent to function IsPageAligned.
    74  func (v Addr) IsPageAligned() bool {
    75  	return IsPageAligned(v)
    76  }
    77  
    78  // AddrRange is a range of Addrs.
    79  //
    80  // type AddrRange <generated by go_generics>
    81  
    82  // ToRange returns [v, v+length).
    83  func (v Addr) ToRange(length uint64) (AddrRange, bool) {
    84  	end, ok := v.AddLength(length)
    85  	return AddrRange{v, end}, ok
    86  }
    87  
    88  // IsPageAligned returns true if ar.Start.IsPageAligned() and
    89  // ar.End.IsPageAligned().
    90  func (ar AddrRange) IsPageAligned() bool {
    91  	return ar.Start.IsPageAligned() && ar.End.IsPageAligned()
    92  }
    93  
    94  // String implements fmt.Stringer.String.
    95  func (ar AddrRange) String() string {
    96  	return fmt.Sprintf("[%#x, %#x)", ar.Start, ar.End)
    97  }