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  }