The Go Programming Language

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

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.