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