github.com/Rookout/GoSDK@v0.1.48/pkg/services/collection/variable/read.go (about) 1 // The MIT License (MIT) 2 3 // Copyright (c) 2014 Derek Parker 4 5 // Permission is hereby granted, free of charge, to any person obtaining a copy of 6 // this software and associated documentation files (the "Software"), to deal in 7 // the Software without restriction, including without limitation the rights to 8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 // the Software, and to permit persons to whom the Software is furnished to do so, 10 // subject to the following conditions: 11 12 // The above copyright notice and this permission notice shall be included in all 13 // copies or substantial portions of the Software. 14 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22 package variable 23 24 import ( 25 "encoding/binary" 26 "fmt" 27 28 "github.com/Rookout/GoSDK/pkg/config" 29 "github.com/Rookout/GoSDK/pkg/services/collection/memory" 30 "github.com/Rookout/GoSDK/pkg/services/instrumentation/binary_info" 31 "github.com/Rookout/GoSDK/pkg/services/instrumentation/dwarf/godwarf" 32 ) 33 34 35 36 func readIntRaw(mem memory.MemoryReader, addr uint64, size int64) (int64, error) { 37 var n int64 38 39 val := make([]byte, int(size)) 40 _, err := mem.ReadMemory(val, addr) 41 if err != nil { 42 return 0, err 43 } 44 45 switch size { 46 case 1: 47 n = int64(int8(val[0])) 48 case 2: 49 n = int64(int16(binary.LittleEndian.Uint16(val))) 50 case 4: 51 n = int64(int32(binary.LittleEndian.Uint32(val))) 52 case 8: 53 n = int64(binary.LittleEndian.Uint64(val)) 54 } 55 56 return n, nil 57 } 58 59 func readUintRaw(mem memory.MemoryReader, addr uint64, size int64) (uint64, error) { 60 var n uint64 61 62 val := make([]byte, int(size)) 63 _, err := mem.ReadMemory(val, addr) 64 if err != nil { 65 return 0, err 66 } 67 68 switch size { 69 case 1: 70 n = uint64(val[0]) 71 case 2: 72 n = uint64(binary.LittleEndian.Uint16(val)) 73 case 4: 74 n = uint64(binary.LittleEndian.Uint32(val)) 75 case 8: 76 n = uint64(binary.LittleEndian.Uint64(val)) 77 } 78 79 return n, nil 80 } 81 82 func readStringInfo(mem memory.MemoryReader, bi *binary_info.BinaryInfo, addr uint64, typ *godwarf.StringType) (uint64, int64, error) { 83 84 85 86 mem = memory.CacheMemory(mem, addr, bi.PointerSize*2) 87 88 var strlen int64 89 var outaddr uint64 90 var err error 91 92 for _, field := range typ.StructType.Field { 93 switch field.Name { 94 case "len": 95 strlen, err = readIntRaw(mem, addr+uint64(field.ByteOffset), int64(bi.PointerSize)) 96 if err != nil { 97 return 0, 0, fmt.Errorf("could not read string len %s", err) 98 } 99 if strlen < 0 { 100 return 0, 0, fmt.Errorf("invalid length: %d", strlen) 101 } 102 case "str": 103 outaddr, err = readUintRaw(mem, addr+uint64(field.ByteOffset), int64(bi.PointerSize)) 104 if err != nil { 105 return 0, 0, fmt.Errorf("could not read string pointer %s", err) 106 } 107 if addr == 0 { 108 return 0, 0, nil 109 } 110 } 111 } 112 113 return outaddr, strlen, nil 114 } 115 116 func readStringValue(mem memory.MemoryReader, addr uint64, strlen int64, cfg config.ObjectDumpConfig) (string, error) { 117 if strlen == 0 { 118 return "", nil 119 } 120 121 count := strlen 122 if count > int64(cfg.MaxString) { 123 count = int64(cfg.MaxString) 124 } 125 126 val := make([]byte, int(count)) 127 _, err := mem.ReadMemory(val, addr) 128 if err != nil { 129 return "", fmt.Errorf("could not read string at %#v due to %s", addr, err) 130 } 131 132 return string(val), nil 133 } 134 135 func readCStringValue(mem memory.MemoryReader, addr uint64, cfg config.ObjectDumpConfig) (string, bool, error) { 136 buf := make([]byte, cfg.MaxString) 137 val := buf[:0] 138 139 for len(buf) > 0 { 140 141 142 143 144 145 146 147 curaddr := addr + uint64(len(val)) 148 maxsize := int(alignAddr(int64(curaddr+1), 1024) - int64(curaddr)) 149 size := len(buf) 150 if size > maxsize { 151 size = maxsize 152 } 153 154 _, err := mem.ReadMemory(buf[:size], curaddr) 155 if err != nil { 156 return "", false, fmt.Errorf("could not read string at %#v due to %s", addr, err) 157 } 158 159 done := false 160 for i := 0; i < size; i++ { 161 if buf[i] == 0 { 162 done = true 163 size = i 164 break 165 } 166 } 167 168 val = val[:len(val)+size] 169 buf = buf[size:] 170 if done { 171 return string(val), true, nil 172 } 173 } 174 175 return string(val), false, nil 176 }