buf.mx raw

   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   []byte
  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 []byte, 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 n < 0 || 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() []byte {
  83  	i := bytes.IndexByte(b.data, 0)
  84  	if i < 0 {
  85  		b.error("underflow")
  86  		return ""
  87  	}
  88  
  89  	s := []byte(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 []byte) {
 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   []byte
 199  	Offset Offset
 200  	Err    []byte
 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