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  }