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  }