github.com/rminnich/u-root@v7.0.0+incompatible/pkg/memio/uintn.go (about)

     1  // Copyright 2012-2019 the u-root 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 memio
     6  
     7  import (
     8  	"fmt"
     9  	"unsafe"
    10  )
    11  
    12  // UintN is a wrapper around uint types and provides a few io-related
    13  // functions.
    14  type UintN interface {
    15  	// Return size in bytes.
    16  	Size() int64
    17  
    18  	// Return string formatted in hex.
    19  	String() string
    20  
    21  	// Read from given address with native endianess.
    22  	read(addr unsafe.Pointer) error
    23  
    24  	// Write to given address with native endianess.
    25  	write(addr unsafe.Pointer) error
    26  }
    27  
    28  // Uint8 is a wrapper around uint8.
    29  type Uint8 uint8
    30  
    31  // Uint16 is a wrapper around uint16.
    32  type Uint16 uint16
    33  
    34  // Uint32 is a wrapper around uint32.
    35  type Uint32 uint32
    36  
    37  // Uint64 is a wrapper around uint64.
    38  type Uint64 uint64
    39  
    40  // ByteSlice is a wrapper around []byte.
    41  type ByteSlice []byte
    42  
    43  // Size of uint8 is 1.
    44  func (u *Uint8) Size() int64 {
    45  	return 1
    46  }
    47  
    48  // Size of uint16 is 2.
    49  func (u *Uint16) Size() int64 {
    50  	return 2
    51  }
    52  
    53  // Size of uint32 is 4.
    54  func (u *Uint32) Size() int64 {
    55  	return 4
    56  }
    57  
    58  // Size of uint64 is 8.
    59  func (u *Uint64) Size() int64 {
    60  	return 8
    61  }
    62  
    63  // Size of []byte.
    64  func (s *ByteSlice) Size() int64 {
    65  	return int64(len(*s))
    66  }
    67  
    68  // String formats a uint8 in hex.
    69  func (u *Uint8) String() string {
    70  	return fmt.Sprintf("%#02x", *u)
    71  }
    72  
    73  // String formats a uint16 in hex.
    74  func (u *Uint16) String() string {
    75  	return fmt.Sprintf("%#04x", *u)
    76  }
    77  
    78  // String formats a uint32 in hex.
    79  func (u *Uint32) String() string {
    80  	return fmt.Sprintf("%#08x", *u)
    81  }
    82  
    83  // String formats a uint64 in hex.
    84  func (u *Uint64) String() string {
    85  	return fmt.Sprintf("%#016x", *u)
    86  }
    87  
    88  // String formats a []byte in hex.
    89  func (s *ByteSlice) String() string {
    90  	return fmt.Sprintf("%#x", *s)
    91  }
    92  
    93  func (u *Uint8) read(addr unsafe.Pointer) error {
    94  	*u = Uint8(*(*uint8)(addr)) // TODO: rewrite in Go assembly for ARM
    95  	return nil                  // TODO: catch misalign, segfault, sigbus, ...
    96  }
    97  
    98  func (u *Uint16) read(addr unsafe.Pointer) error {
    99  	*u = Uint16(*(*uint16)(addr)) // TODO: rewrite in Go assembly for ARM
   100  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
   101  }
   102  
   103  func (u *Uint32) read(addr unsafe.Pointer) error {
   104  	*u = Uint32(*(*uint32)(addr)) // TODO: rewrite in Go assembly for ARM
   105  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
   106  }
   107  
   108  func (u *Uint64) read(addr unsafe.Pointer) error {
   109  	// Warning: On arm, this uses two ldr's rather than ldrd.
   110  	*u = Uint64(*(*uint64)(addr)) // TODO: rewrite in Go assembly for ARM
   111  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
   112  }
   113  
   114  func (s *ByteSlice) read(addr unsafe.Pointer) error {
   115  	for i := 0; i < len(*s); i++ {
   116  		(*s)[i] = *(*byte)(addr)
   117  		addr = unsafe.Pointer(uintptr(addr) + 1)
   118  	}
   119  	return nil // TODO: catch misalign, segfault, sigbus, ...
   120  }
   121  
   122  func (u *Uint8) write(addr unsafe.Pointer) error {
   123  	*(*uint8)(addr) = uint8(*u) // TODO: rewrite in Go assembly for ARM
   124  	return nil                  // TODO: catch misalign, segfault, sigbus, ...
   125  }
   126  
   127  func (u *Uint16) write(addr unsafe.Pointer) error {
   128  	*(*uint16)(addr) = uint16(*u) // TODO: rewrite in Go assembly for ARM
   129  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
   130  }
   131  
   132  func (u *Uint32) write(addr unsafe.Pointer) error {
   133  	*(*uint32)(addr) = uint32(*u) // TODO: rewrite in Go assembly for ARM
   134  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
   135  }
   136  
   137  func (u *Uint64) write(addr unsafe.Pointer) error {
   138  	// Warning: On arm, this uses two str's rather than strd.
   139  	*(*uint64)(addr) = uint64(*u) // TODO: rewrite in Go assembly for ARM
   140  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
   141  }
   142  
   143  func (s *ByteSlice) write(addr unsafe.Pointer) error {
   144  	for i := 0; i < len(*s); i++ {
   145  		*(*byte)(addr) = (*s)[i]
   146  		addr = unsafe.Pointer(uintptr(addr) + 1)
   147  	}
   148  	return nil // TODO: catch misalign, segfault, sigbus, ...
   149  }