...

Source file src/pkg/debug/dwarf/unit.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	package dwarf
     6	
     7	import (
     8		"sort"
     9		"strconv"
    10	)
    11	
    12	// DWARF debug info is split into a sequence of compilation units.
    13	// Each unit has its own abbreviation table and address size.
    14	
    15	type unit struct {
    16		base   Offset // byte offset of header within the aggregate info
    17		off    Offset // byte offset of data within the aggregate info
    18		data   []byte
    19		atable abbrevTable
    20		asize  int
    21		vers   int
    22		is64   bool // True for 64-bit DWARF format
    23	}
    24	
    25	// Implement the dataFormat interface.
    26	
    27	func (u *unit) version() int {
    28		return u.vers
    29	}
    30	
    31	func (u *unit) dwarf64() (bool, bool) {
    32		return u.is64, true
    33	}
    34	
    35	func (u *unit) addrsize() int {
    36		return u.asize
    37	}
    38	
    39	func (d *Data) parseUnits() ([]unit, error) {
    40		// Count units.
    41		nunit := 0
    42		b := makeBuf(d, unknownFormat{}, "info", 0, d.info)
    43		for len(b.data) > 0 {
    44			len, _ := b.unitLength()
    45			if len != Offset(uint32(len)) {
    46				b.error("unit length overflow")
    47				break
    48			}
    49			b.skip(int(len))
    50			nunit++
    51		}
    52		if b.err != nil {
    53			return nil, b.err
    54		}
    55	
    56		// Again, this time writing them down.
    57		b = makeBuf(d, unknownFormat{}, "info", 0, d.info)
    58		units := make([]unit, nunit)
    59		for i := range units {
    60			u := &units[i]
    61			u.base = b.off
    62			var n Offset
    63			n, u.is64 = b.unitLength()
    64			dataOff := b.off
    65			vers := b.uint16()
    66			if vers != 2 && vers != 3 && vers != 4 {
    67				b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
    68				break
    69			}
    70			u.vers = int(vers)
    71			var abbrevOff uint64
    72			if u.is64 {
    73				abbrevOff = b.uint64()
    74			} else {
    75				abbrevOff = uint64(b.uint32())
    76			}
    77			atable, err := d.parseAbbrev(abbrevOff, u.vers)
    78			if err != nil {
    79				if b.err == nil {
    80					b.err = err
    81				}
    82				break
    83			}
    84			u.atable = atable
    85			u.asize = int(b.uint8())
    86			u.off = b.off
    87			u.data = b.bytes(int(n - (b.off - dataOff)))
    88		}
    89		if b.err != nil {
    90			return nil, b.err
    91		}
    92		return units, nil
    93	}
    94	
    95	// offsetToUnit returns the index of the unit containing offset off.
    96	// It returns -1 if no unit contains this offset.
    97	func (d *Data) offsetToUnit(off Offset) int {
    98		// Find the unit after off
    99		next := sort.Search(len(d.unit), func(i int) bool {
   100			return d.unit[i].off > off
   101		})
   102		if next == 0 {
   103			return -1
   104		}
   105		u := &d.unit[next-1]
   106		if u.off <= off && off < u.off+Offset(len(u.data)) {
   107			return next - 1
   108		}
   109		return -1
   110	}
   111	

View as plain text