Source file src/debug/dwarf/buf.go

Documentation: debug/dwarf

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Buffered reading and decoding of DWARF data streams.
     6  
     7  package dwarf
     8  
     9  import (
    10  	"encoding/binary"
    11  	"strconv"
    12  )
    13  
    14  // Data buffer being decoded.
    15  type buf struct {
    16  	dwarf  *Data
    17  	order  binary.ByteOrder
    18  	format dataFormat
    19  	name   string
    20  	off    Offset
    21  	data   []byte
    22  	err    error
    23  }
    24  
    25  // Data format, other than byte order. This affects the handling of
    26  // certain field formats.
    27  type dataFormat interface {
    28  	// DWARF version number. Zero means unknown.
    29  	version() int
    30  
    31  	// 64-bit DWARF format?
    32  	dwarf64() (dwarf64 bool, isKnown bool)
    33  
    34  	// Size of an address, in bytes. Zero means unknown.
    35  	addrsize() int
    36  }
    37  
    38  // Some parts of DWARF have no data format, e.g., abbrevs.
    39  type unknownFormat struct{}
    40  
    41  func (u unknownFormat) version() int {
    42  	return 0
    43  }
    44  
    45  func (u unknownFormat) dwarf64() (bool, bool) {
    46  	return false, false
    47  }
    48  
    49  func (u unknownFormat) addrsize() int {
    50  	return 0
    51  }
    52  
    53  func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf {
    54  	return buf{d, d.order, format, name, off, data, nil}
    55  }
    56  
    57  func (b *buf) uint8() uint8 {
    58  	if len(b.data) < 1 {
    59  		b.error("underflow")
    60  		return 0
    61  	}
    62  	val := b.data[0]
    63  	b.data = b.data[1:]
    64  	b.off++
    65  	return val
    66  }
    67  
    68  func (b *buf) bytes(n int) []byte {
    69  	if len(b.data) < n {
    70  		b.error("underflow")
    71  		return nil
    72  	}
    73  	data := b.data[0:n]
    74  	b.data = b.data[n:]
    75  	b.off += Offset(n)
    76  	return data
    77  }
    78  
    79  func (b *buf) skip(n int) { b.bytes(n) }
    80  
    81  func (b *buf) string() string {
    82  	for i := 0; i < len(b.data); i++ {
    83  		if b.data[i] == 0 {
    84  			s := string(b.data[0:i])
    85  			b.data = b.data[i+1:]
    86  			b.off += Offset(i + 1)
    87  			return s
    88  		}
    89  	}
    90  	b.error("underflow")
    91  	return ""
    92  }
    93  
    94  func (b *buf) uint16() uint16 {
    95  	a := b.bytes(2)
    96  	if a == nil {
    97  		return 0
    98  	}
    99  	return b.order.Uint16(a)
   100  }
   101  
   102  func (b *buf) uint32() uint32 {
   103  	a := b.bytes(4)
   104  	if a == nil {
   105  		return 0
   106  	}
   107  	return b.order.Uint32(a)
   108  }
   109  
   110  func (b *buf) uint64() uint64 {
   111  	a := b.bytes(8)
   112  	if a == nil {
   113  		return 0
   114  	}
   115  	return b.order.Uint64(a)
   116  }
   117  
   118  // Read a varint, which is 7 bits per byte, little endian.
   119  // the 0x80 bit means read another byte.
   120  func (b *buf) varint() (c uint64, bits uint) {
   121  	for i := 0; i < len(b.data); i++ {
   122  		byte := b.data[i]
   123  		c |= uint64(byte&0x7F) << bits
   124  		bits += 7
   125  		if byte&0x80 == 0 {
   126  			b.off += Offset(i + 1)
   127  			b.data = b.data[i+1:]
   128  			return c, bits
   129  		}
   130  	}
   131  	return 0, 0
   132  }
   133  
   134  // Unsigned int is just a varint.
   135  func (b *buf) uint() uint64 {
   136  	x, _ := b.varint()
   137  	return x
   138  }
   139  
   140  // Signed int is a sign-extended varint.
   141  func (b *buf) int() int64 {
   142  	ux, bits := b.varint()
   143  	x := int64(ux)
   144  	if x&(1<<(bits-1)) != 0 {
   145  		x |= -1 << bits
   146  	}
   147  	return x
   148  }
   149  
   150  // Address-sized uint.
   151  func (b *buf) addr() uint64 {
   152  	switch b.format.addrsize() {
   153  	case 1:
   154  		return uint64(b.uint8())
   155  	case 2:
   156  		return uint64(b.uint16())
   157  	case 4:
   158  		return uint64(b.uint32())
   159  	case 8:
   160  		return b.uint64()
   161  	}
   162  	b.error("unknown address size")
   163  	return 0
   164  }
   165  
   166  func (b *buf) unitLength() (length Offset, dwarf64 bool) {
   167  	length = Offset(b.uint32())
   168  	if length == 0xffffffff {
   169  		dwarf64 = true
   170  		length = Offset(b.uint64())
   171  	} else if length >= 0xfffffff0 {
   172  		b.error("unit length has reserved value")
   173  	}
   174  	return
   175  }
   176  
   177  func (b *buf) error(s string) {
   178  	if b.err == nil {
   179  		b.data = nil
   180  		b.err = DecodeError{b.name, b.off, s}
   181  	}
   182  }
   183  
   184  type DecodeError struct {
   185  	Name   string
   186  	Offset Offset
   187  	Err    string
   188  }
   189  
   190  func (e DecodeError) Error() string {
   191  	return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err
   192  }
   193  

View as plain text