gitlab.com/apertussolutions/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 }