Source file src/debug/dwarf/buf.go

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

View as plain text