Plan 9 from Bell Labs’s /usr/web/sources/contrib/ericvh/go-plan9/src/pkg/debug/dwarf/buf.go

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Buffered reading and decoding of DWARF data streams.

package dwarf

import (
	"encoding/binary";
	"os";
	"strconv";
)

// Data buffer being decoded.
type buf struct {
	dwarf		*Data;
	order		binary.ByteOrder;
	name		string;
	off		Offset;
	data		[]byte;
	addrsize	int;
	err		os.Error;
}

func makeBuf(d *Data, name string, off Offset, data []byte, addrsize int) buf {
	return buf{d, d.order, name, off, data, addrsize, nil}
}

func (b *buf) uint8() uint8 {
	if len(b.data) < 1 {
		b.error("underflow");
		return 0;
	}
	val := b.data[0];
	b.data = b.data[1:];
	b.off++;
	return val;
}

func (b *buf) bytes(n int) []byte {
	if len(b.data) < n {
		b.error("underflow");
		return nil;
	}
	data := b.data[0:n];
	b.data = b.data[n:];
	b.off += Offset(n);
	return data;
}

func (b *buf) skip(n int)	{ b.bytes(n) }

func (b *buf) string() string {
	for i := 0; i < len(b.data); i++ {
		if b.data[i] == 0 {
			s := string(b.data[0:i]);
			b.data = b.data[i+1:];
			b.off += Offset(i + 1);
			return s;
		}
	}
	b.error("underflow");
	return "";
}

func (b *buf) uint16() uint16 {
	a := b.bytes(2);
	if a == nil {
		return 0
	}
	return b.order.Uint16(a);
}

func (b *buf) uint32() uint32 {
	a := b.bytes(4);
	if a == nil {
		return 0
	}
	return b.order.Uint32(a);
}

func (b *buf) uint64() uint64 {
	a := b.bytes(8);
	if a == nil {
		return 0
	}
	return b.order.Uint64(a);
}

// Read a varint, which is 7 bits per byte, little endian.
// the 0x80 bit means read another byte.
func (b *buf) varint() (c uint64, bits uint) {
	for i := 0; i < len(b.data); i++ {
		byte := b.data[i];
		c |= uint64(byte&0x7F) << bits;
		bits += 7;
		if byte&0x80 == 0 {
			b.off += Offset(i + 1);
			b.data = b.data[i+1:];
			return c, bits;
		}
	}
	return 0, 0;
}

// Unsigned int is just a varint.
func (b *buf) uint() uint64 {
	x, _ := b.varint();
	return x;
}

// Signed int is a sign-extended varint.
func (b *buf) int() int64 {
	ux, bits := b.varint();
	x := int64(ux);
	if x&(1<<(bits-1)) != 0 {
		x |= -1 << bits
	}
	return x;
}

// Address-sized uint.
func (b *buf) addr() uint64 {
	switch b.addrsize {
	case 1:
		return uint64(b.uint8())
	case 2:
		return uint64(b.uint16())
	case 4:
		return uint64(b.uint32())
	case 8:
		return uint64(b.uint64())
	}
	b.error("unknown address size");
	return 0;
}

func (b *buf) error(s string) {
	if b.err == nil {
		b.data = nil;
		b.err = DecodeError{b.name, b.off, s};
	}
}

type DecodeError struct {
	Name	string;
	Offset	Offset;
	Error	string;
}

func (e DecodeError) String() string {
	return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.Itob64(int64(e.Offset), 16) + ": " + e.Error
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.