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