123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- // 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 (
- "bytes"
- "encoding/binary"
- "strconv"
- )
- // Data buffer being decoded.
- type buf struct {
- dwarf *Data
- order binary.ByteOrder
- format dataFormat
- name string
- off Offset
- data []byte
- err error
- }
- // Data format, other than byte order. This affects the handling of
- // certain field formats.
- type dataFormat interface {
- // DWARF version number. Zero means unknown.
- version() int
- // 64-bit DWARF format?
- dwarf64() (dwarf64 bool, isKnown bool)
- // Size of an address, in bytes. Zero means unknown.
- addrsize() int
- }
- // Some parts of DWARF have no data format, e.g., abbrevs.
- type unknownFormat struct{}
- func (u unknownFormat) version() int {
- return 0
- }
- func (u unknownFormat) dwarf64() (bool, bool) {
- return false, false
- }
- func (u unknownFormat) addrsize() int {
- return 0
- }
- func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf {
- return buf{d, d.order, format, name, off, data, 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 {
- i := bytes.IndexByte(b.data, 0)
- if i < 0 {
- b.error("underflow")
- return ""
- }
- s := string(b.data[0:i])
- b.data = b.data[i+1:]
- b.off += Offset(i + 1)
- return s
- }
- func (b *buf) uint16() uint16 {
- a := b.bytes(2)
- if a == nil {
- return 0
- }
- return b.order.Uint16(a)
- }
- func (b *buf) uint24() uint32 {
- a := b.bytes(3)
- if a == nil {
- return 0
- }
- if b.dwarf.bigEndian {
- return uint32(a[2]) | uint32(a[1])<<8 | uint32(a[0])<<16
- } else {
- return uint32(a[0]) | uint32(a[1])<<8 | uint32(a[2])<<16
- }
- }
- 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.format.addrsize() {
- case 1:
- return uint64(b.uint8())
- case 2:
- return uint64(b.uint16())
- case 4:
- return uint64(b.uint32())
- case 8:
- return b.uint64()
- }
- b.error("unknown address size")
- return 0
- }
- func (b *buf) unitLength() (length Offset, dwarf64 bool) {
- length = Offset(b.uint32())
- if length == 0xffffffff {
- dwarf64 = true
- length = Offset(b.uint64())
- } else if length >= 0xfffffff0 {
- b.error("unit length has reserved value")
- }
- return
- }
- 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
- Err string
- }
- func (e DecodeError) Error() string {
- return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err
- }
|