src/pkg/debug/dwarf/buf.go - The Go Programming Language

Golang

Source file src/pkg/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		"encoding/binary"
    11		"strconv"
    12	)
    13	
    14	// Data buffer being decoded.
    15	type buf struct {
    16		dwarf    *Data
    17		order    binary.ByteOrder
    18		name     string
    19		off      Offset
    20		data     []byte
    21		addrsize int
    22		err      error
    23	}
    24	
    25	func makeBuf(d *Data, name string, off Offset, data []byte, addrsize int) buf {
    26		return buf{d, d.order, name, off, data, addrsize, nil}
    27	}
    28	
    29	func (b *buf) uint8() uint8 {
    30		if len(b.data) < 1 {
    31			b.error("underflow")
    32			return 0
    33		}
    34		val := b.data[0]
    35		b.data = b.data[1:]
    36		b.off++
    37		return val
    38	}
    39	
    40	func (b *buf) bytes(n int) []byte {
    41		if len(b.data) < n {
    42			b.error("underflow")
    43			return nil
    44		}
    45		data := b.data[0:n]
    46		b.data = b.data[n:]
    47		b.off += Offset(n)
    48		return data
    49	}
    50	
    51	func (b *buf) skip(n int) { b.bytes(n) }
    52	
    53	func (b *buf) string() string {
    54		for i := 0; i < len(b.data); i++ {
    55			if b.data[i] == 0 {
    56				s := string(b.data[0:i])
    57				b.data = b.data[i+1:]
    58				b.off += Offset(i + 1)
    59				return s
    60			}
    61		}
    62		b.error("underflow")
    63		return ""
    64	}
    65	
    66	func (b *buf) uint16() uint16 {
    67		a := b.bytes(2)
    68		if a == nil {
    69			return 0
    70		}
    71		return b.order.Uint16(a)
    72	}
    73	
    74	func (b *buf) uint32() uint32 {
    75		a := b.bytes(4)
    76		if a == nil {
    77			return 0
    78		}
    79		return b.order.Uint32(a)
    80	}
    81	
    82	func (b *buf) uint64() uint64 {
    83		a := b.bytes(8)
    84		if a == nil {
    85			return 0
    86		}
    87		return b.order.Uint64(a)
    88	}
    89	
    90	// Read a varint, which is 7 bits per byte, little endian.
    91	// the 0x80 bit means read another byte.
    92	func (b *buf) varint() (c uint64, bits uint) {
    93		for i := 0; i < len(b.data); i++ {
    94			byte := b.data[i]
    95			c |= uint64(byte&0x7F) << bits
    96			bits += 7
    97			if byte&0x80 == 0 {
    98				b.off += Offset(i + 1)
    99				b.data = b.data[i+1:]
   100				return c, bits
   101			}
   102		}
   103		return 0, 0
   104	}
   105	
   106	// Unsigned int is just a varint.
   107	func (b *buf) uint() uint64 {
   108		x, _ := b.varint()
   109		return x
   110	}
   111	
   112	// Signed int is a sign-extended varint.
   113	func (b *buf) int() int64 {
   114		ux, bits := b.varint()
   115		x := int64(ux)
   116		if x&(1<<(bits-1)) != 0 {
   117			x |= -1 << bits
   118		}
   119		return x
   120	}
   121	
   122	// Address-sized uint.
   123	func (b *buf) addr() uint64 {
   124		switch b.addrsize {
   125		case 1:
   126			return uint64(b.uint8())
   127		case 2:
   128			return uint64(b.uint16())
   129		case 4:
   130			return uint64(b.uint32())
   131		case 8:
   132			return uint64(b.uint64())
   133		}
   134		b.error("unknown address size")
   135		return 0
   136	}
   137	
   138	func (b *buf) error(s string) {
   139		if b.err == nil {
   140			b.data = nil
   141			b.err = DecodeError{b.name, b.off, s}
   142		}
   143	}
   144	
   145	type DecodeError struct {
   146		Name   string
   147		Offset Offset
   148		Err    string
   149	}
   150	
   151	func (e DecodeError) Error() string {
   152		return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err
   153	}