github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/pkg/strace/print.go (about) 1 // Copyright 2018 Google LLC. 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 // Changes are Copyright 2018 the u-root Authors. 16 17 package strace 18 19 import ( 20 "fmt" 21 "strings" 22 23 "golang.org/x/sys/unix" 24 ) 25 26 // DefaultLogMaximumSize is the default LogMaximumSize. 27 const DefaultLogMaximumSize = 1024 28 29 // LogMaximumSize determines the maximum display size for data blobs (read, 30 // write, etc.). 31 var LogMaximumSize uint = DefaultLogMaximumSize 32 33 // EventMaximumSize determines the maximum size for data blobs (read, write, 34 // etc.) sent over the event channel. Default is 0 because most clients cannot 35 // do anything useful with binary text dump of byte array arguments. 36 var EventMaximumSize uint 37 38 func dump(t *Tracer, addr Addr, size uint, maximumBlobSize uint) string { 39 origSize := size 40 if size > maximumBlobSize { 41 size = maximumBlobSize 42 } 43 if size == 0 { 44 return "" 45 } 46 47 b := make([]byte, size) 48 amt, err := t.Read(addr, b) 49 if err != nil { 50 return fmt.Sprintf("%#x (error decoding string: %s)", addr, err) 51 } 52 53 dot := "" 54 if uint(amt) < origSize { 55 // ... if we truncated the dump. 56 dot = "..." 57 } 58 59 return fmt.Sprintf("%#x %q%s", addr, b[:amt], dot) 60 } 61 62 func iovecs(t *Tracer, addr Addr, iovcnt int, printContent bool, maxBytes uint64) string { 63 if iovcnt < 0 || iovcnt > 0x10 /*unix.MSG_MAXIOVLEN*/ { 64 return fmt.Sprintf("%#x (error decoding iovecs: invalid iovcnt)", addr) 65 } 66 v := make([]iovec, iovcnt) 67 _, err := t.Read(addr, v) 68 if err != nil { 69 return fmt.Sprintf("%#x (error decoding iovecs: %v)", addr, err) 70 } 71 72 var totalBytes uint64 73 var truncated bool 74 iovs := make([]string, iovcnt) 75 for i, vv := range v { 76 if vv.S == 0 || !printContent { 77 iovs[i] = fmt.Sprintf("{base=%#x, len=%d}", vv.P, vv.S) 78 continue 79 } 80 81 size := uint64(vv.S) 82 if truncated || totalBytes+size > maxBytes { 83 truncated = true 84 size = maxBytes - totalBytes 85 } else { 86 totalBytes += uint64(vv.S) 87 } 88 89 b := make([]byte, size) 90 amt, err := t.Read(vv.P, b) 91 if err != nil { 92 iovs[i] = fmt.Sprintf("{base=%#x, len=%d, %q..., error decoding string: %v}", vv.P, vv.S, b[:amt], err) 93 continue 94 } 95 96 dot := "" 97 if truncated { 98 // Indicate truncation. 99 dot = "..." 100 } 101 iovs[i] = fmt.Sprintf("{base=%#x, len=%d, %q%s}", vv.P, vv.S, b[:amt], dot) 102 } 103 104 return fmt.Sprintf("%#x %s", addr, strings.Join(iovs, ", ")) 105 } 106 107 func fdpair(t *Tracer, addr Addr) string { 108 var fds [2]int32 109 _, err := t.Read(addr, &fds) 110 if err != nil { 111 return fmt.Sprintf("%#x (error decoding fds: %s)", addr, err) 112 } 113 114 return fmt.Sprintf("%#x [%d %d]", addr, fds[0], fds[1]) 115 } 116 117 func uname(t *Tracer, addr Addr) string { 118 var u unix.Utsname 119 if _, err := t.Read(addr, &u); err != nil { 120 return fmt.Sprintf("%#x (error decoding utsname: %s)", addr, err) 121 } 122 123 return fmt.Sprintf("%#x %v", addr, u) 124 } 125 126 // AlignUp rounds a length up to an alignment. align must be a power of 2. 127 func AlignUp(length int, align uint) int { 128 return (length + int(align) - 1) & ^(int(align) - 1) 129 } 130 131 // AlignDown rounds a down to an alignment. align must be a power of 2. 132 func AlignDown(length int, align uint) int { 133 return length & ^(int(align) - 1) 134 }