github.com/Rookout/GoSDK@v0.1.48/pkg/services/instrumentation/dwarf/line/parse_util.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 line 23 24 import ( 25 "bytes" 26 "encoding/binary" 27 "errors" 28 29 "github.com/Rookout/GoSDK/pkg/services/instrumentation/dwarf/util" 30 ) 31 32 const ( 33 _DW_FORM_block = 0x09 34 _DW_FORM_block1 = 0x0a 35 _DW_FORM_block2 = 0x03 36 _DW_FORM_block4 = 0x04 37 _DW_FORM_data1 = 0x0b 38 _DW_FORM_data2 = 0x05 39 _DW_FORM_data4 = 0x06 40 _DW_FORM_data8 = 0x07 41 _DW_FORM_data16 = 0x1e 42 _DW_FORM_flag = 0x0c 43 _DW_FORM_line_strp = 0x1f 44 _DW_FORM_sdata = 0x0d 45 _DW_FORM_sec_offset = 0x17 46 _DW_FORM_string = 0x08 47 _DW_FORM_strp = 0x0e 48 _DW_FORM_strx = 0x1a 49 _DW_FORM_strx1 = 0x25 50 _DW_FORM_strx2 = 0x26 51 _DW_FORM_strx3 = 0x27 52 _DW_FORM_strx4 = 0x28 53 _DW_FORM_udata = 0x0f 54 ) 55 56 const ( 57 _DW_LNCT_path = 0x1 + iota 58 _DW_LNCT_directory_index 59 _DW_LNCT_timestamp 60 _DW_LNCT_size 61 _DW_LNCT_MD5 62 ) 63 64 var ErrBufferUnderflow = errors.New("buffer underflow") 65 66 type formReader struct { 67 logf func(string, ...interface{}) 68 contentTypes []uint64 69 formCodes []uint64 70 71 contentType uint64 72 formCode uint64 73 74 block []byte 75 u64 uint64 76 i64 int64 77 str string 78 err error 79 80 nexti int 81 } 82 83 func readEntryFormat(buf *bytes.Buffer, logf func(string, ...interface{})) *formReader { 84 if buf.Len() < 1 { 85 return nil 86 } 87 count := buf.Next(1)[0] 88 r := &formReader{ 89 logf: logf, 90 contentTypes: make([]uint64, count), 91 formCodes: make([]uint64, count), 92 } 93 for i := range r.contentTypes { 94 r.contentTypes[i], _ = util.DecodeULEB128(buf) 95 r.formCodes[i], _ = util.DecodeULEB128(buf) 96 } 97 return r 98 } 99 100 func (rdr *formReader) reset() { 101 rdr.err = nil 102 rdr.nexti = 0 103 } 104 105 func (rdr *formReader) next(buf *bytes.Buffer) bool { 106 if rdr.err != nil { 107 return false 108 } 109 if rdr.nexti >= len(rdr.contentTypes) { 110 return false 111 } 112 113 rdr.contentType = rdr.contentTypes[rdr.nexti] 114 rdr.formCode = rdr.formCodes[rdr.nexti] 115 116 switch rdr.formCode { 117 case _DW_FORM_block: 118 n, _ := util.DecodeULEB128(buf) 119 rdr.readBlock(buf, n) 120 121 case _DW_FORM_block1: 122 if buf.Len() < 1 { 123 rdr.err = ErrBufferUnderflow 124 return false 125 } 126 rdr.readBlock(buf, uint64(buf.Next(1)[0])) 127 128 case _DW_FORM_block2: 129 if buf.Len() < 2 { 130 rdr.err = ErrBufferUnderflow 131 return false 132 } 133 rdr.readBlock(buf, uint64(binary.LittleEndian.Uint16(buf.Next(2)))) 134 135 case _DW_FORM_block4: 136 if buf.Len() < 4 { 137 rdr.err = ErrBufferUnderflow 138 return false 139 } 140 rdr.readBlock(buf, uint64(binary.LittleEndian.Uint32(buf.Next(4)))) 141 142 case _DW_FORM_data1, _DW_FORM_flag, _DW_FORM_strx1: 143 if buf.Len() < 1 { 144 rdr.err = ErrBufferUnderflow 145 return false 146 } 147 rdr.u64 = uint64(buf.Next(1)[0]) 148 149 case _DW_FORM_data2, _DW_FORM_strx2: 150 if buf.Len() < 2 { 151 rdr.err = ErrBufferUnderflow 152 return false 153 } 154 rdr.u64 = uint64(binary.LittleEndian.Uint16(buf.Next(2))) 155 156 case _DW_FORM_data4, _DW_FORM_line_strp, _DW_FORM_sec_offset, _DW_FORM_strp, _DW_FORM_strx4: 157 if buf.Len() < 4 { 158 rdr.err = ErrBufferUnderflow 159 return false 160 } 161 rdr.u64 = uint64(binary.LittleEndian.Uint32(buf.Next(4))) 162 163 case _DW_FORM_data8: 164 if buf.Len() < 8 { 165 rdr.err = ErrBufferUnderflow 166 return false 167 } 168 rdr.u64 = binary.LittleEndian.Uint64(buf.Next(8)) 169 170 case _DW_FORM_data16: 171 rdr.readBlock(buf, 16) 172 173 case _DW_FORM_sdata: 174 rdr.i64, _ = util.DecodeSLEB128(buf) 175 176 case _DW_FORM_udata, _DW_FORM_strx: 177 rdr.u64, _ = util.DecodeULEB128(buf) 178 179 case _DW_FORM_string: 180 rdr.str, _ = util.ParseString(buf) 181 182 case _DW_FORM_strx3: 183 if buf.Len() < 3 { 184 rdr.err = ErrBufferUnderflow 185 return false 186 } 187 rdr.u64 = uint64(binary.LittleEndian.Uint32(append(buf.Next(3), 0x0))) 188 189 case ^uint64(0): 190 191 192 default: 193 if rdr.logf != nil { 194 rdr.logf("unknown form code %#x", rdr.formCode) 195 } 196 rdr.formCodes[rdr.nexti] = ^uint64(0) 197 } 198 199 rdr.nexti++ 200 return true 201 } 202 203 func (rdr *formReader) readBlock(buf *bytes.Buffer, n uint64) { 204 if uint64(buf.Len()) < n { 205 rdr.err = ErrBufferUnderflow 206 return 207 } 208 if cap(rdr.block) < int(n) { 209 rdr.block = make([]byte, 0, n) 210 } 211 rdr.block = rdr.block[:n] 212 buf.Read(rdr.block) 213 }