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