...

Source file src/debug/dwarf/entry.go

Documentation: debug/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  // DWARF debug information entry parser.
		 6  // An entry is a sequence of data items of a given format.
		 7  // The first word in the entry is an index into what DWARF
		 8  // calls the ``abbreviation table.''	An abbreviation is really
		 9  // just a type descriptor: it's an array of attribute tag/value format pairs.
		10  
		11  package dwarf
		12  
		13  import (
		14  	"encoding/binary"
		15  	"errors"
		16  	"strconv"
		17  )
		18  
		19  // a single entry's description: a sequence of attributes
		20  type abbrev struct {
		21  	tag			Tag
		22  	children bool
		23  	field		[]afield
		24  }
		25  
		26  type afield struct {
		27  	attr	Attr
		28  	fmt	 format
		29  	class Class
		30  	val	 int64 // for formImplicitConst
		31  }
		32  
		33  // a map from entry format ids to their descriptions
		34  type abbrevTable map[uint32]abbrev
		35  
		36  // ParseAbbrev returns the abbreviation table that starts at byte off
		37  // in the .debug_abbrev section.
		38  func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) {
		39  	if m, ok := d.abbrevCache[off]; ok {
		40  		return m, nil
		41  	}
		42  
		43  	data := d.abbrev
		44  	if off > uint64(len(data)) {
		45  		data = nil
		46  	} else {
		47  		data = data[off:]
		48  	}
		49  	b := makeBuf(d, unknownFormat{}, "abbrev", 0, data)
		50  
		51  	// Error handling is simplified by the buf getters
		52  	// returning an endless stream of 0s after an error.
		53  	m := make(abbrevTable)
		54  	for {
		55  		// Table ends with id == 0.
		56  		id := uint32(b.uint())
		57  		if id == 0 {
		58  			break
		59  		}
		60  
		61  		// Walk over attributes, counting.
		62  		n := 0
		63  		b1 := b // Read from copy of b.
		64  		b1.uint()
		65  		b1.uint8()
		66  		for {
		67  			tag := b1.uint()
		68  			fmt := b1.uint()
		69  			if tag == 0 && fmt == 0 {
		70  				break
		71  			}
		72  			if format(fmt) == formImplicitConst {
		73  				b1.int()
		74  			}
		75  			n++
		76  		}
		77  		if b1.err != nil {
		78  			return nil, b1.err
		79  		}
		80  
		81  		// Walk over attributes again, this time writing them down.
		82  		var a abbrev
		83  		a.tag = Tag(b.uint())
		84  		a.children = b.uint8() != 0
		85  		a.field = make([]afield, n)
		86  		for i := range a.field {
		87  			a.field[i].attr = Attr(b.uint())
		88  			a.field[i].fmt = format(b.uint())
		89  			a.field[i].class = formToClass(a.field[i].fmt, a.field[i].attr, vers, &b)
		90  			if a.field[i].fmt == formImplicitConst {
		91  				a.field[i].val = b.int()
		92  			}
		93  		}
		94  		b.uint()
		95  		b.uint()
		96  
		97  		m[id] = a
		98  	}
		99  	if b.err != nil {
	 100  		return nil, b.err
	 101  	}
	 102  	d.abbrevCache[off] = m
	 103  	return m, nil
	 104  }
	 105  
	 106  // attrIsExprloc indicates attributes that allow exprloc values that
	 107  // are encoded as block values in DWARF 2 and 3. See DWARF 4, Figure
	 108  // 20.
	 109  var attrIsExprloc = map[Attr]bool{
	 110  	AttrLocation:			true,
	 111  	AttrByteSize:			true,
	 112  	AttrBitOffset:		 true,
	 113  	AttrBitSize:			 true,
	 114  	AttrStringLength:	true,
	 115  	AttrLowerBound:		true,
	 116  	AttrReturnAddr:		true,
	 117  	AttrStrideSize:		true,
	 118  	AttrUpperBound:		true,
	 119  	AttrCount:				 true,
	 120  	AttrDataMemberLoc: true,
	 121  	AttrFrameBase:		 true,
	 122  	AttrSegment:			 true,
	 123  	AttrStaticLink:		true,
	 124  	AttrUseLocation:	 true,
	 125  	AttrVtableElemLoc: true,
	 126  	AttrAllocated:		 true,
	 127  	AttrAssociated:		true,
	 128  	AttrDataLocation:	true,
	 129  	AttrStride:				true,
	 130  }
	 131  
	 132  // attrPtrClass indicates the *ptr class of attributes that have
	 133  // encoding formSecOffset in DWARF 4 or formData* in DWARF 2 and 3.
	 134  var attrPtrClass = map[Attr]Class{
	 135  	AttrLocation:			ClassLocListPtr,
	 136  	AttrStmtList:			ClassLinePtr,
	 137  	AttrStringLength:	ClassLocListPtr,
	 138  	AttrReturnAddr:		ClassLocListPtr,
	 139  	AttrStartScope:		ClassRangeListPtr,
	 140  	AttrDataMemberLoc: ClassLocListPtr,
	 141  	AttrFrameBase:		 ClassLocListPtr,
	 142  	AttrMacroInfo:		 ClassMacPtr,
	 143  	AttrSegment:			 ClassLocListPtr,
	 144  	AttrStaticLink:		ClassLocListPtr,
	 145  	AttrUseLocation:	 ClassLocListPtr,
	 146  	AttrVtableElemLoc: ClassLocListPtr,
	 147  	AttrRanges:				ClassRangeListPtr,
	 148  	// The following are new in DWARF 5.
	 149  	AttrStrOffsetsBase: ClassStrOffsetsPtr,
	 150  	AttrAddrBase:			 ClassAddrPtr,
	 151  	AttrRnglistsBase:	 ClassRngListsPtr,
	 152  	AttrLoclistsBase:	 ClassLocListPtr,
	 153  }
	 154  
	 155  // formToClass returns the DWARF 4 Class for the given form. If the
	 156  // DWARF version is less then 4, it will disambiguate some forms
	 157  // depending on the attribute.
	 158  func formToClass(form format, attr Attr, vers int, b *buf) Class {
	 159  	switch form {
	 160  	default:
	 161  		b.error("cannot determine class of unknown attribute form")
	 162  		return 0
	 163  
	 164  	case formIndirect:
	 165  		return ClassUnknown
	 166  
	 167  	case formAddr, formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4:
	 168  		return ClassAddress
	 169  
	 170  	case formDwarfBlock1, formDwarfBlock2, formDwarfBlock4, formDwarfBlock:
	 171  		// In DWARF 2 and 3, ClassExprLoc was encoded as a
	 172  		// block. DWARF 4 distinguishes ClassBlock and
	 173  		// ClassExprLoc, but there are no attributes that can
	 174  		// be both, so we also promote ClassBlock values in
	 175  		// DWARF 4 that should be ClassExprLoc in case
	 176  		// producers get this wrong.
	 177  		if attrIsExprloc[attr] {
	 178  			return ClassExprLoc
	 179  		}
	 180  		return ClassBlock
	 181  
	 182  	case formData1, formData2, formData4, formData8, formSdata, formUdata, formData16, formImplicitConst:
	 183  		// In DWARF 2 and 3, ClassPtr was encoded as a
	 184  		// constant. Unlike ClassExprLoc/ClassBlock, some
	 185  		// DWARF 4 attributes need to distinguish Class*Ptr
	 186  		// from ClassConstant, so we only do this promotion
	 187  		// for versions 2 and 3.
	 188  		if class, ok := attrPtrClass[attr]; vers < 4 && ok {
	 189  			return class
	 190  		}
	 191  		return ClassConstant
	 192  
	 193  	case formFlag, formFlagPresent:
	 194  		return ClassFlag
	 195  
	 196  	case formRefAddr, formRef1, formRef2, formRef4, formRef8, formRefUdata, formRefSup4, formRefSup8:
	 197  		return ClassReference
	 198  
	 199  	case formRefSig8:
	 200  		return ClassReferenceSig
	 201  
	 202  	case formString, formStrp, formStrx, formStrpSup, formLineStrp, formStrx1, formStrx2, formStrx3, formStrx4:
	 203  		return ClassString
	 204  
	 205  	case formSecOffset:
	 206  		// DWARF 4 defines four *ptr classes, but doesn't
	 207  		// distinguish them in the encoding. Disambiguate
	 208  		// these classes using the attribute.
	 209  		if class, ok := attrPtrClass[attr]; ok {
	 210  			return class
	 211  		}
	 212  		return ClassUnknown
	 213  
	 214  	case formExprloc:
	 215  		return ClassExprLoc
	 216  
	 217  	case formGnuRefAlt:
	 218  		return ClassReferenceAlt
	 219  
	 220  	case formGnuStrpAlt:
	 221  		return ClassStringAlt
	 222  
	 223  	case formLoclistx:
	 224  		return ClassLocList
	 225  
	 226  	case formRnglistx:
	 227  		return ClassRngList
	 228  	}
	 229  }
	 230  
	 231  // An entry is a sequence of attribute/value pairs.
	 232  type Entry struct {
	 233  	Offset	 Offset // offset of Entry in DWARF info
	 234  	Tag			Tag		// tag (kind of Entry)
	 235  	Children bool	 // whether Entry is followed by children
	 236  	Field		[]Field
	 237  }
	 238  
	 239  // A Field is a single attribute/value pair in an Entry.
	 240  //
	 241  // A value can be one of several "attribute classes" defined by DWARF.
	 242  // The Go types corresponding to each class are:
	 243  //
	 244  //		DWARF class			 Go type				Class
	 245  //		-----------			 -------				-----
	 246  //		address					 uint64				 ClassAddress
	 247  //		block						 []byte				 ClassBlock
	 248  //		constant					int64					ClassConstant
	 249  //		flag							bool					 ClassFlag
	 250  //		reference
	 251  //			to info				 dwarf.Offset	 ClassReference
	 252  //			to type unit		uint64				 ClassReferenceSig
	 253  //		string						string				 ClassString
	 254  //		exprloc					 []byte				 ClassExprLoc
	 255  //		lineptr					 int64					ClassLinePtr
	 256  //		loclistptr				int64					ClassLocListPtr
	 257  //		macptr						int64					ClassMacPtr
	 258  //		rangelistptr			int64					ClassRangeListPtr
	 259  //
	 260  // For unrecognized or vendor-defined attributes, Class may be
	 261  // ClassUnknown.
	 262  type Field struct {
	 263  	Attr	Attr
	 264  	Val	 interface{}
	 265  	Class Class
	 266  }
	 267  
	 268  // A Class is the DWARF 4 class of an attribute value.
	 269  //
	 270  // In general, a given attribute's value may take on one of several
	 271  // possible classes defined by DWARF, each of which leads to a
	 272  // slightly different interpretation of the attribute.
	 273  //
	 274  // DWARF version 4 distinguishes attribute value classes more finely
	 275  // than previous versions of DWARF. The reader will disambiguate
	 276  // coarser classes from earlier versions of DWARF into the appropriate
	 277  // DWARF 4 class. For example, DWARF 2 uses "constant" for constants
	 278  // as well as all types of section offsets, but the reader will
	 279  // canonicalize attributes in DWARF 2 files that refer to section
	 280  // offsets to one of the Class*Ptr classes, even though these classes
	 281  // were only defined in DWARF 3.
	 282  type Class int
	 283  
	 284  const (
	 285  	// ClassUnknown represents values of unknown DWARF class.
	 286  	ClassUnknown Class = iota
	 287  
	 288  	// ClassAddress represents values of type uint64 that are
	 289  	// addresses on the target machine.
	 290  	ClassAddress
	 291  
	 292  	// ClassBlock represents values of type []byte whose
	 293  	// interpretation depends on the attribute.
	 294  	ClassBlock
	 295  
	 296  	// ClassConstant represents values of type int64 that are
	 297  	// constants. The interpretation of this constant depends on
	 298  	// the attribute.
	 299  	ClassConstant
	 300  
	 301  	// ClassExprLoc represents values of type []byte that contain
	 302  	// an encoded DWARF expression or location description.
	 303  	ClassExprLoc
	 304  
	 305  	// ClassFlag represents values of type bool.
	 306  	ClassFlag
	 307  
	 308  	// ClassLinePtr represents values that are an int64 offset
	 309  	// into the "line" section.
	 310  	ClassLinePtr
	 311  
	 312  	// ClassLocListPtr represents values that are an int64 offset
	 313  	// into the "loclist" section.
	 314  	ClassLocListPtr
	 315  
	 316  	// ClassMacPtr represents values that are an int64 offset into
	 317  	// the "mac" section.
	 318  	ClassMacPtr
	 319  
	 320  	// ClassRangeListPtr represents values that are an int64 offset into
	 321  	// the "rangelist" section.
	 322  	ClassRangeListPtr
	 323  
	 324  	// ClassReference represents values that are an Offset offset
	 325  	// of an Entry in the info section (for use with Reader.Seek).
	 326  	// The DWARF specification combines ClassReference and
	 327  	// ClassReferenceSig into class "reference".
	 328  	ClassReference
	 329  
	 330  	// ClassReferenceSig represents values that are a uint64 type
	 331  	// signature referencing a type Entry.
	 332  	ClassReferenceSig
	 333  
	 334  	// ClassString represents values that are strings. If the
	 335  	// compilation unit specifies the AttrUseUTF8 flag (strongly
	 336  	// recommended), the string value will be encoded in UTF-8.
	 337  	// Otherwise, the encoding is unspecified.
	 338  	ClassString
	 339  
	 340  	// ClassReferenceAlt represents values of type int64 that are
	 341  	// an offset into the DWARF "info" section of an alternate
	 342  	// object file.
	 343  	ClassReferenceAlt
	 344  
	 345  	// ClassStringAlt represents values of type int64 that are an
	 346  	// offset into the DWARF string section of an alternate object
	 347  	// file.
	 348  	ClassStringAlt
	 349  
	 350  	// ClassAddrPtr represents values that are an int64 offset
	 351  	// into the "addr" section.
	 352  	ClassAddrPtr
	 353  
	 354  	// ClassLocList represents values that are an int64 offset
	 355  	// into the "loclists" section.
	 356  	ClassLocList
	 357  
	 358  	// ClassRngList represents values that are a uint64 offset
	 359  	// from the base of the "rnglists" section.
	 360  	ClassRngList
	 361  
	 362  	// ClassRngListsPtr represents values that are an int64 offset
	 363  	// into the "rnglists" section. These are used as the base for
	 364  	// ClassRngList values.
	 365  	ClassRngListsPtr
	 366  
	 367  	// ClassStrOffsetsPtr represents values that are an int64
	 368  	// offset into the "str_offsets" section.
	 369  	ClassStrOffsetsPtr
	 370  )
	 371  
	 372  //go:generate stringer -type=Class
	 373  
	 374  func (i Class) GoString() string {
	 375  	return "dwarf." + i.String()
	 376  }
	 377  
	 378  // Val returns the value associated with attribute Attr in Entry,
	 379  // or nil if there is no such attribute.
	 380  //
	 381  // A common idiom is to merge the check for nil return with
	 382  // the check that the value has the expected dynamic type, as in:
	 383  //	v, ok := e.Val(AttrSibling).(int64)
	 384  //
	 385  func (e *Entry) Val(a Attr) interface{} {
	 386  	if f := e.AttrField(a); f != nil {
	 387  		return f.Val
	 388  	}
	 389  	return nil
	 390  }
	 391  
	 392  // AttrField returns the Field associated with attribute Attr in
	 393  // Entry, or nil if there is no such attribute.
	 394  func (e *Entry) AttrField(a Attr) *Field {
	 395  	for i, f := range e.Field {
	 396  		if f.Attr == a {
	 397  			return &e.Field[i]
	 398  		}
	 399  	}
	 400  	return nil
	 401  }
	 402  
	 403  // An Offset represents the location of an Entry within the DWARF info.
	 404  // (See Reader.Seek.)
	 405  type Offset uint32
	 406  
	 407  // Entry reads a single entry from buf, decoding
	 408  // according to the given abbreviation table.
	 409  func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry {
	 410  	off := b.off
	 411  	id := uint32(b.uint())
	 412  	if id == 0 {
	 413  		return &Entry{}
	 414  	}
	 415  	a, ok := atab[id]
	 416  	if !ok {
	 417  		b.error("unknown abbreviation table index")
	 418  		return nil
	 419  	}
	 420  	e := &Entry{
	 421  		Offset:	 off,
	 422  		Tag:			a.tag,
	 423  		Children: a.children,
	 424  		Field:		make([]Field, len(a.field)),
	 425  	}
	 426  
	 427  	// If we are currently parsing the compilation unit,
	 428  	// we can't evaluate Addrx or Strx until we've seen the
	 429  	// relevant base entry.
	 430  	type delayed struct {
	 431  		idx int
	 432  		off uint64
	 433  		fmt format
	 434  	}
	 435  	var delay []delayed
	 436  
	 437  	resolveStrx := func(strBase, off uint64) string {
	 438  		off += strBase
	 439  		if uint64(int(off)) != off {
	 440  			b.error("DW_FORM_strx offset out of range")
	 441  		}
	 442  
	 443  		b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets)
	 444  		b1.skip(int(off))
	 445  		is64, _ := b.format.dwarf64()
	 446  		if is64 {
	 447  			off = b1.uint64()
	 448  		} else {
	 449  			off = uint64(b1.uint32())
	 450  		}
	 451  		if b1.err != nil {
	 452  			b.err = b1.err
	 453  			return ""
	 454  		}
	 455  		if uint64(int(off)) != off {
	 456  			b.error("DW_FORM_strx indirect offset out of range")
	 457  		}
	 458  		b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
	 459  		b1.skip(int(off))
	 460  		val := b1.string()
	 461  		if b1.err != nil {
	 462  			b.err = b1.err
	 463  		}
	 464  		return val
	 465  	}
	 466  
	 467  	resolveRnglistx := func(rnglistsBase, off uint64) uint64 {
	 468  		is64, _ := b.format.dwarf64()
	 469  		if is64 {
	 470  			off *= 8
	 471  		} else {
	 472  			off *= 4
	 473  		}
	 474  		off += rnglistsBase
	 475  		if uint64(int(off)) != off {
	 476  			b.error("DW_FORM_rnglistx offset out of range")
	 477  		}
	 478  
	 479  		b1 := makeBuf(b.dwarf, b.format, "rnglists", 0, b.dwarf.rngLists)
	 480  		b1.skip(int(off))
	 481  		if is64 {
	 482  			off = b1.uint64()
	 483  		} else {
	 484  			off = uint64(b1.uint32())
	 485  		}
	 486  		if b1.err != nil {
	 487  			b.err = b1.err
	 488  			return 0
	 489  		}
	 490  		if uint64(int(off)) != off {
	 491  			b.error("DW_FORM_rnglistx indirect offset out of range")
	 492  		}
	 493  		return rnglistsBase + off
	 494  	}
	 495  
	 496  	for i := range e.Field {
	 497  		e.Field[i].Attr = a.field[i].attr
	 498  		e.Field[i].Class = a.field[i].class
	 499  		fmt := a.field[i].fmt
	 500  		if fmt == formIndirect {
	 501  			fmt = format(b.uint())
	 502  			e.Field[i].Class = formToClass(fmt, a.field[i].attr, vers, b)
	 503  		}
	 504  		var val interface{}
	 505  		switch fmt {
	 506  		default:
	 507  			b.error("unknown entry attr format 0x" + strconv.FormatInt(int64(fmt), 16))
	 508  
	 509  		// address
	 510  		case formAddr:
	 511  			val = b.addr()
	 512  		case formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4:
	 513  			var off uint64
	 514  			switch fmt {
	 515  			case formAddrx:
	 516  				off = b.uint()
	 517  			case formAddrx1:
	 518  				off = uint64(b.uint8())
	 519  			case formAddrx2:
	 520  				off = uint64(b.uint16())
	 521  			case formAddrx3:
	 522  				off = uint64(b.uint24())
	 523  			case formAddrx4:
	 524  				off = uint64(b.uint32())
	 525  			}
	 526  			if b.dwarf.addr == nil {
	 527  				b.error("DW_FORM_addrx with no .debug_addr section")
	 528  			}
	 529  			if b.err != nil {
	 530  				return nil
	 531  			}
	 532  
	 533  			// We have to adjust by the offset of the
	 534  			// compilation unit. This won't work if the
	 535  			// program uses Reader.Seek to skip over the
	 536  			// unit. Not much we can do about that.
	 537  			var addrBase int64
	 538  			if cu != nil {
	 539  				addrBase, _ = cu.Val(AttrAddrBase).(int64)
	 540  			} else if a.tag == TagCompileUnit {
	 541  				delay = append(delay, delayed{i, off, formAddrx})
	 542  				break
	 543  			}
	 544  
	 545  			var err error
	 546  			val, err = b.dwarf.debugAddr(b.format, uint64(addrBase), off)
	 547  			if err != nil {
	 548  				if b.err == nil {
	 549  					b.err = err
	 550  				}
	 551  				return nil
	 552  			}
	 553  
	 554  		// block
	 555  		case formDwarfBlock1:
	 556  			val = b.bytes(int(b.uint8()))
	 557  		case formDwarfBlock2:
	 558  			val = b.bytes(int(b.uint16()))
	 559  		case formDwarfBlock4:
	 560  			val = b.bytes(int(b.uint32()))
	 561  		case formDwarfBlock:
	 562  			val = b.bytes(int(b.uint()))
	 563  
	 564  		// constant
	 565  		case formData1:
	 566  			val = int64(b.uint8())
	 567  		case formData2:
	 568  			val = int64(b.uint16())
	 569  		case formData4:
	 570  			val = int64(b.uint32())
	 571  		case formData8:
	 572  			val = int64(b.uint64())
	 573  		case formData16:
	 574  			val = b.bytes(16)
	 575  		case formSdata:
	 576  			val = int64(b.int())
	 577  		case formUdata:
	 578  			val = int64(b.uint())
	 579  		case formImplicitConst:
	 580  			val = a.field[i].val
	 581  
	 582  		// flag
	 583  		case formFlag:
	 584  			val = b.uint8() == 1
	 585  		// New in DWARF 4.
	 586  		case formFlagPresent:
	 587  			// The attribute is implicitly indicated as present, and no value is
	 588  			// encoded in the debugging information entry itself.
	 589  			val = true
	 590  
	 591  		// reference to other entry
	 592  		case formRefAddr:
	 593  			vers := b.format.version()
	 594  			if vers == 0 {
	 595  				b.error("unknown version for DW_FORM_ref_addr")
	 596  			} else if vers == 2 {
	 597  				val = Offset(b.addr())
	 598  			} else {
	 599  				is64, known := b.format.dwarf64()
	 600  				if !known {
	 601  					b.error("unknown size for DW_FORM_ref_addr")
	 602  				} else if is64 {
	 603  					val = Offset(b.uint64())
	 604  				} else {
	 605  					val = Offset(b.uint32())
	 606  				}
	 607  			}
	 608  		case formRef1:
	 609  			val = Offset(b.uint8()) + ubase
	 610  		case formRef2:
	 611  			val = Offset(b.uint16()) + ubase
	 612  		case formRef4:
	 613  			val = Offset(b.uint32()) + ubase
	 614  		case formRef8:
	 615  			val = Offset(b.uint64()) + ubase
	 616  		case formRefUdata:
	 617  			val = Offset(b.uint()) + ubase
	 618  
	 619  		// string
	 620  		case formString:
	 621  			val = b.string()
	 622  		case formStrp, formLineStrp:
	 623  			var off uint64 // offset into .debug_str
	 624  			is64, known := b.format.dwarf64()
	 625  			if !known {
	 626  				b.error("unknown size for DW_FORM_strp/line_strp")
	 627  			} else if is64 {
	 628  				off = b.uint64()
	 629  			} else {
	 630  				off = uint64(b.uint32())
	 631  			}
	 632  			if uint64(int(off)) != off {
	 633  				b.error("DW_FORM_strp/line_strp offset out of range")
	 634  			}
	 635  			if b.err != nil {
	 636  				return nil
	 637  			}
	 638  			var b1 buf
	 639  			if fmt == formStrp {
	 640  				b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
	 641  			} else {
	 642  				if len(b.dwarf.lineStr) == 0 {
	 643  					b.error("DW_FORM_line_strp with no .debug_line_str section")
	 644  				}
	 645  				b1 = makeBuf(b.dwarf, b.format, "line_str", 0, b.dwarf.lineStr)
	 646  			}
	 647  			b1.skip(int(off))
	 648  			val = b1.string()
	 649  			if b1.err != nil {
	 650  				b.err = b1.err
	 651  				return nil
	 652  			}
	 653  		case formStrx, formStrx1, formStrx2, formStrx3, formStrx4:
	 654  			var off uint64
	 655  			switch fmt {
	 656  			case formStrx:
	 657  				off = b.uint()
	 658  			case formStrx1:
	 659  				off = uint64(b.uint8())
	 660  			case formStrx2:
	 661  				off = uint64(b.uint16())
	 662  			case formStrx3:
	 663  				off = uint64(b.uint24())
	 664  			case formStrx4:
	 665  				off = uint64(b.uint32())
	 666  			}
	 667  			if len(b.dwarf.strOffsets) == 0 {
	 668  				b.error("DW_FORM_strx with no .debug_str_offsets section")
	 669  			}
	 670  			is64, known := b.format.dwarf64()
	 671  			if !known {
	 672  				b.error("unknown offset size for DW_FORM_strx")
	 673  			}
	 674  			if b.err != nil {
	 675  				return nil
	 676  			}
	 677  			if is64 {
	 678  				off *= 8
	 679  			} else {
	 680  				off *= 4
	 681  			}
	 682  
	 683  			// We have to adjust by the offset of the
	 684  			// compilation unit. This won't work if the
	 685  			// program uses Reader.Seek to skip over the
	 686  			// unit. Not much we can do about that.
	 687  			var strBase int64
	 688  			if cu != nil {
	 689  				strBase, _ = cu.Val(AttrStrOffsetsBase).(int64)
	 690  			} else if a.tag == TagCompileUnit {
	 691  				delay = append(delay, delayed{i, off, formStrx})
	 692  				break
	 693  			}
	 694  
	 695  			val = resolveStrx(uint64(strBase), off)
	 696  
	 697  		case formStrpSup:
	 698  			is64, known := b.format.dwarf64()
	 699  			if !known {
	 700  				b.error("unknown size for DW_FORM_strp_sup")
	 701  			} else if is64 {
	 702  				val = b.uint64()
	 703  			} else {
	 704  				val = b.uint32()
	 705  			}
	 706  
	 707  		// lineptr, loclistptr, macptr, rangelistptr
	 708  		// New in DWARF 4, but clang can generate them with -gdwarf-2.
	 709  		// Section reference, replacing use of formData4 and formData8.
	 710  		case formSecOffset, formGnuRefAlt, formGnuStrpAlt:
	 711  			is64, known := b.format.dwarf64()
	 712  			if !known {
	 713  				b.error("unknown size for form 0x" + strconv.FormatInt(int64(fmt), 16))
	 714  			} else if is64 {
	 715  				val = int64(b.uint64())
	 716  			} else {
	 717  				val = int64(b.uint32())
	 718  			}
	 719  
	 720  		// exprloc
	 721  		// New in DWARF 4.
	 722  		case formExprloc:
	 723  			val = b.bytes(int(b.uint()))
	 724  
	 725  		// reference
	 726  		// New in DWARF 4.
	 727  		case formRefSig8:
	 728  			// 64-bit type signature.
	 729  			val = b.uint64()
	 730  		case formRefSup4:
	 731  			val = b.uint32()
	 732  		case formRefSup8:
	 733  			val = b.uint64()
	 734  
	 735  		// loclist
	 736  		case formLoclistx:
	 737  			val = b.uint()
	 738  
	 739  		// rnglist
	 740  		case formRnglistx:
	 741  			off := b.uint()
	 742  
	 743  			// We have to adjust by the rnglists_base of
	 744  			// the compilation unit. This won't work if
	 745  			// the program uses Reader.Seek to skip over
	 746  			// the unit. Not much we can do about that.
	 747  			var rnglistsBase int64
	 748  			if cu != nil {
	 749  				rnglistsBase, _ = cu.Val(AttrRnglistsBase).(int64)
	 750  			} else if a.tag == TagCompileUnit {
	 751  				delay = append(delay, delayed{i, off, formRnglistx})
	 752  				break
	 753  			}
	 754  
	 755  			val = resolveRnglistx(uint64(rnglistsBase), off)
	 756  		}
	 757  
	 758  		e.Field[i].Val = val
	 759  	}
	 760  	if b.err != nil {
	 761  		return nil
	 762  	}
	 763  
	 764  	for _, del := range delay {
	 765  		switch del.fmt {
	 766  		case formAddrx:
	 767  			addrBase, _ := e.Val(AttrAddrBase).(int64)
	 768  			val, err := b.dwarf.debugAddr(b.format, uint64(addrBase), del.off)
	 769  			if err != nil {
	 770  				b.err = err
	 771  				return nil
	 772  			}
	 773  			e.Field[del.idx].Val = val
	 774  		case formStrx:
	 775  			strBase, _ := e.Val(AttrStrOffsetsBase).(int64)
	 776  			e.Field[del.idx].Val = resolveStrx(uint64(strBase), del.off)
	 777  			if b.err != nil {
	 778  				return nil
	 779  			}
	 780  		case formRnglistx:
	 781  			rnglistsBase, _ := e.Val(AttrRnglistsBase).(int64)
	 782  			e.Field[del.idx].Val = resolveRnglistx(uint64(rnglistsBase), del.off)
	 783  			if b.err != nil {
	 784  				return nil
	 785  			}
	 786  		}
	 787  	}
	 788  
	 789  	return e
	 790  }
	 791  
	 792  // A Reader allows reading Entry structures from a DWARF ``info'' section.
	 793  // The Entry structures are arranged in a tree. The Reader's Next function
	 794  // return successive entries from a pre-order traversal of the tree.
	 795  // If an entry has children, its Children field will be true, and the children
	 796  // follow, terminated by an Entry with Tag 0.
	 797  type Reader struct {
	 798  	b						buf
	 799  	d						*Data
	 800  	err					error
	 801  	unit				 int
	 802  	lastUnit		 bool	 // set if last entry returned by Next is TagCompileUnit/TagPartialUnit
	 803  	lastChildren bool	 // .Children of last entry returned by Next
	 804  	lastSibling	Offset // .Val(AttrSibling) of last entry returned by Next
	 805  	cu					 *Entry // current compilation unit
	 806  }
	 807  
	 808  // Reader returns a new Reader for Data.
	 809  // The reader is positioned at byte offset 0 in the DWARF ``info'' section.
	 810  func (d *Data) Reader() *Reader {
	 811  	r := &Reader{d: d}
	 812  	r.Seek(0)
	 813  	return r
	 814  }
	 815  
	 816  // AddressSize returns the size in bytes of addresses in the current compilation
	 817  // unit.
	 818  func (r *Reader) AddressSize() int {
	 819  	return r.d.unit[r.unit].asize
	 820  }
	 821  
	 822  // ByteOrder returns the byte order in the current compilation unit.
	 823  func (r *Reader) ByteOrder() binary.ByteOrder {
	 824  	return r.b.order
	 825  }
	 826  
	 827  // Seek positions the Reader at offset off in the encoded entry stream.
	 828  // Offset 0 can be used to denote the first entry.
	 829  func (r *Reader) Seek(off Offset) {
	 830  	d := r.d
	 831  	r.err = nil
	 832  	r.lastChildren = false
	 833  	if off == 0 {
	 834  		if len(d.unit) == 0 {
	 835  			return
	 836  		}
	 837  		u := &d.unit[0]
	 838  		r.unit = 0
	 839  		r.b = makeBuf(r.d, u, "info", u.off, u.data)
	 840  		r.cu = nil
	 841  		return
	 842  	}
	 843  
	 844  	i := d.offsetToUnit(off)
	 845  	if i == -1 {
	 846  		r.err = errors.New("offset out of range")
	 847  		return
	 848  	}
	 849  	if i != r.unit {
	 850  		r.cu = nil
	 851  	}
	 852  	u := &d.unit[i]
	 853  	r.unit = i
	 854  	r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:])
	 855  }
	 856  
	 857  // maybeNextUnit advances to the next unit if this one is finished.
	 858  func (r *Reader) maybeNextUnit() {
	 859  	for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) {
	 860  		r.nextUnit()
	 861  	}
	 862  }
	 863  
	 864  // nextUnit advances to the next unit.
	 865  func (r *Reader) nextUnit() {
	 866  	r.unit++
	 867  	u := &r.d.unit[r.unit]
	 868  	r.b = makeBuf(r.d, u, "info", u.off, u.data)
	 869  	r.cu = nil
	 870  }
	 871  
	 872  // Next reads the next entry from the encoded entry stream.
	 873  // It returns nil, nil when it reaches the end of the section.
	 874  // It returns an error if the current offset is invalid or the data at the
	 875  // offset cannot be decoded as a valid Entry.
	 876  func (r *Reader) Next() (*Entry, error) {
	 877  	if r.err != nil {
	 878  		return nil, r.err
	 879  	}
	 880  	r.maybeNextUnit()
	 881  	if len(r.b.data) == 0 {
	 882  		return nil, nil
	 883  	}
	 884  	u := &r.d.unit[r.unit]
	 885  	e := r.b.entry(r.cu, u.atable, u.base, u.vers)
	 886  	if r.b.err != nil {
	 887  		r.err = r.b.err
	 888  		return nil, r.err
	 889  	}
	 890  	r.lastUnit = false
	 891  	if e != nil {
	 892  		r.lastChildren = e.Children
	 893  		if r.lastChildren {
	 894  			r.lastSibling, _ = e.Val(AttrSibling).(Offset)
	 895  		}
	 896  		if e.Tag == TagCompileUnit || e.Tag == TagPartialUnit {
	 897  			r.lastUnit = true
	 898  			r.cu = e
	 899  		}
	 900  	} else {
	 901  		r.lastChildren = false
	 902  	}
	 903  	return e, nil
	 904  }
	 905  
	 906  // SkipChildren skips over the child entries associated with
	 907  // the last Entry returned by Next. If that Entry did not have
	 908  // children or Next has not been called, SkipChildren is a no-op.
	 909  func (r *Reader) SkipChildren() {
	 910  	if r.err != nil || !r.lastChildren {
	 911  		return
	 912  	}
	 913  
	 914  	// If the last entry had a sibling attribute,
	 915  	// that attribute gives the offset of the next
	 916  	// sibling, so we can avoid decoding the
	 917  	// child subtrees.
	 918  	if r.lastSibling >= r.b.off {
	 919  		r.Seek(r.lastSibling)
	 920  		return
	 921  	}
	 922  
	 923  	if r.lastUnit && r.unit+1 < len(r.d.unit) {
	 924  		r.nextUnit()
	 925  		return
	 926  	}
	 927  
	 928  	for {
	 929  		e, err := r.Next()
	 930  		if err != nil || e == nil || e.Tag == 0 {
	 931  			break
	 932  		}
	 933  		if e.Children {
	 934  			r.SkipChildren()
	 935  		}
	 936  	}
	 937  }
	 938  
	 939  // clone returns a copy of the reader. This is used by the typeReader
	 940  // interface.
	 941  func (r *Reader) clone() typeReader {
	 942  	return r.d.Reader()
	 943  }
	 944  
	 945  // offset returns the current buffer offset. This is used by the
	 946  // typeReader interface.
	 947  func (r *Reader) offset() Offset {
	 948  	return r.b.off
	 949  }
	 950  
	 951  // SeekPC returns the Entry for the compilation unit that includes pc,
	 952  // and positions the reader to read the children of that unit.	If pc
	 953  // is not covered by any unit, SeekPC returns ErrUnknownPC and the
	 954  // position of the reader is undefined.
	 955  //
	 956  // Because compilation units can describe multiple regions of the
	 957  // executable, in the worst case SeekPC must search through all the
	 958  // ranges in all the compilation units. Each call to SeekPC starts the
	 959  // search at the compilation unit of the last call, so in general
	 960  // looking up a series of PCs will be faster if they are sorted. If
	 961  // the caller wishes to do repeated fast PC lookups, it should build
	 962  // an appropriate index using the Ranges method.
	 963  func (r *Reader) SeekPC(pc uint64) (*Entry, error) {
	 964  	unit := r.unit
	 965  	for i := 0; i < len(r.d.unit); i++ {
	 966  		if unit >= len(r.d.unit) {
	 967  			unit = 0
	 968  		}
	 969  		r.err = nil
	 970  		r.lastChildren = false
	 971  		r.unit = unit
	 972  		r.cu = nil
	 973  		u := &r.d.unit[unit]
	 974  		r.b = makeBuf(r.d, u, "info", u.off, u.data)
	 975  		e, err := r.Next()
	 976  		if err != nil {
	 977  			return nil, err
	 978  		}
	 979  		ranges, err := r.d.Ranges(e)
	 980  		if err != nil {
	 981  			return nil, err
	 982  		}
	 983  		for _, pcs := range ranges {
	 984  			if pcs[0] <= pc && pc < pcs[1] {
	 985  				return e, nil
	 986  			}
	 987  		}
	 988  		unit++
	 989  	}
	 990  	return nil, ErrUnknownPC
	 991  }
	 992  
	 993  // Ranges returns the PC ranges covered by e, a slice of [low,high) pairs.
	 994  // Only some entry types, such as TagCompileUnit or TagSubprogram, have PC
	 995  // ranges; for others, this will return nil with no error.
	 996  func (d *Data) Ranges(e *Entry) ([][2]uint64, error) {
	 997  	var ret [][2]uint64
	 998  
	 999  	low, lowOK := e.Val(AttrLowpc).(uint64)
	1000  
	1001  	var high uint64
	1002  	var highOK bool
	1003  	highField := e.AttrField(AttrHighpc)
	1004  	if highField != nil {
	1005  		switch highField.Class {
	1006  		case ClassAddress:
	1007  			high, highOK = highField.Val.(uint64)
	1008  		case ClassConstant:
	1009  			off, ok := highField.Val.(int64)
	1010  			if ok {
	1011  				high = low + uint64(off)
	1012  				highOK = true
	1013  			}
	1014  		}
	1015  	}
	1016  
	1017  	if lowOK && highOK {
	1018  		ret = append(ret, [2]uint64{low, high})
	1019  	}
	1020  
	1021  	var u *unit
	1022  	if uidx := d.offsetToUnit(e.Offset); uidx >= 0 && uidx < len(d.unit) {
	1023  		u = &d.unit[uidx]
	1024  	}
	1025  
	1026  	if u != nil && u.vers >= 5 && d.rngLists != nil {
	1027  		// DWARF version 5 and later
	1028  		field := e.AttrField(AttrRanges)
	1029  		if field == nil {
	1030  			return ret, nil
	1031  		}
	1032  		switch field.Class {
	1033  		case ClassRangeListPtr:
	1034  			ranges, rangesOK := field.Val.(int64)
	1035  			if !rangesOK {
	1036  				return ret, nil
	1037  			}
	1038  			cu, base, err := d.baseAddressForEntry(e)
	1039  			if err != nil {
	1040  				return nil, err
	1041  			}
	1042  			return d.dwarf5Ranges(u, cu, base, ranges, ret)
	1043  
	1044  		case ClassRngList:
	1045  			rnglist, ok := field.Val.(uint64)
	1046  			if !ok {
	1047  				return ret, nil
	1048  			}
	1049  			cu, base, err := d.baseAddressForEntry(e)
	1050  			if err != nil {
	1051  				return nil, err
	1052  			}
	1053  			return d.dwarf5Ranges(u, cu, base, int64(rnglist), ret)
	1054  
	1055  		default:
	1056  			return ret, nil
	1057  		}
	1058  	}
	1059  
	1060  	// DWARF version 2 through 4
	1061  	ranges, rangesOK := e.Val(AttrRanges).(int64)
	1062  	if rangesOK && d.ranges != nil {
	1063  		_, base, err := d.baseAddressForEntry(e)
	1064  		if err != nil {
	1065  			return nil, err
	1066  		}
	1067  		return d.dwarf2Ranges(u, base, ranges, ret)
	1068  	}
	1069  
	1070  	return ret, nil
	1071  }
	1072  
	1073  // baseAddressForEntry returns the initial base address to be used when
	1074  // looking up the range list of entry e.
	1075  // DWARF specifies that this should be the lowpc attribute of the enclosing
	1076  // compilation unit, however comments in gdb/dwarf2read.c say that some
	1077  // versions of GCC use the entrypc attribute, so we check that too.
	1078  func (d *Data) baseAddressForEntry(e *Entry) (*Entry, uint64, error) {
	1079  	var cu *Entry
	1080  	if e.Tag == TagCompileUnit {
	1081  		cu = e
	1082  	} else {
	1083  		i := d.offsetToUnit(e.Offset)
	1084  		if i == -1 {
	1085  			return nil, 0, errors.New("no unit for entry")
	1086  		}
	1087  		u := &d.unit[i]
	1088  		b := makeBuf(d, u, "info", u.off, u.data)
	1089  		cu = b.entry(nil, u.atable, u.base, u.vers)
	1090  		if b.err != nil {
	1091  			return nil, 0, b.err
	1092  		}
	1093  	}
	1094  
	1095  	if cuEntry, cuEntryOK := cu.Val(AttrEntrypc).(uint64); cuEntryOK {
	1096  		return cu, cuEntry, nil
	1097  	} else if cuLow, cuLowOK := cu.Val(AttrLowpc).(uint64); cuLowOK {
	1098  		return cu, cuLow, nil
	1099  	}
	1100  
	1101  	return cu, 0, nil
	1102  }
	1103  
	1104  func (d *Data) dwarf2Ranges(u *unit, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
	1105  	buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:])
	1106  	for len(buf.data) > 0 {
	1107  		low := buf.addr()
	1108  		high := buf.addr()
	1109  
	1110  		if low == 0 && high == 0 {
	1111  			break
	1112  		}
	1113  
	1114  		if low == ^uint64(0)>>uint((8-u.addrsize())*8) {
	1115  			base = high
	1116  		} else {
	1117  			ret = append(ret, [2]uint64{base + low, base + high})
	1118  		}
	1119  	}
	1120  
	1121  	return ret, nil
	1122  }
	1123  
	1124  // dwarf5Ranges interpets a debug_rnglists sequence, see DWARFv5 section
	1125  // 2.17.3 (page 53).
	1126  func (d *Data) dwarf5Ranges(u *unit, cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
	1127  	var addrBase int64
	1128  	if cu != nil {
	1129  		addrBase, _ = cu.Val(AttrAddrBase).(int64)
	1130  	}
	1131  
	1132  	buf := makeBuf(d, u, "rnglists", 0, d.rngLists)
	1133  	buf.skip(int(ranges))
	1134  	for {
	1135  		opcode := buf.uint8()
	1136  		switch opcode {
	1137  		case rleEndOfList:
	1138  			if buf.err != nil {
	1139  				return nil, buf.err
	1140  			}
	1141  			return ret, nil
	1142  
	1143  		case rleBaseAddressx:
	1144  			baseIdx := buf.uint()
	1145  			var err error
	1146  			base, err = d.debugAddr(u, uint64(addrBase), baseIdx)
	1147  			if err != nil {
	1148  				return nil, err
	1149  			}
	1150  
	1151  		case rleStartxEndx:
	1152  			startIdx := buf.uint()
	1153  			endIdx := buf.uint()
	1154  
	1155  			start, err := d.debugAddr(u, uint64(addrBase), startIdx)
	1156  			if err != nil {
	1157  				return nil, err
	1158  			}
	1159  			end, err := d.debugAddr(u, uint64(addrBase), endIdx)
	1160  			if err != nil {
	1161  				return nil, err
	1162  			}
	1163  			ret = append(ret, [2]uint64{start, end})
	1164  
	1165  		case rleStartxLength:
	1166  			startIdx := buf.uint()
	1167  			len := buf.uint()
	1168  			start, err := d.debugAddr(u, uint64(addrBase), startIdx)
	1169  			if err != nil {
	1170  				return nil, err
	1171  			}
	1172  			ret = append(ret, [2]uint64{start, start + len})
	1173  
	1174  		case rleOffsetPair:
	1175  			off1 := buf.uint()
	1176  			off2 := buf.uint()
	1177  			ret = append(ret, [2]uint64{base + off1, base + off2})
	1178  
	1179  		case rleBaseAddress:
	1180  			base = buf.addr()
	1181  
	1182  		case rleStartEnd:
	1183  			start := buf.addr()
	1184  			end := buf.addr()
	1185  			ret = append(ret, [2]uint64{start, end})
	1186  
	1187  		case rleStartLength:
	1188  			start := buf.addr()
	1189  			len := buf.uint()
	1190  			ret = append(ret, [2]uint64{start, start + len})
	1191  		}
	1192  	}
	1193  }
	1194  
	1195  // debugAddr returns the address at idx in debug_addr
	1196  func (d *Data) debugAddr(format dataFormat, addrBase, idx uint64) (uint64, error) {
	1197  	off := idx*uint64(format.addrsize()) + addrBase
	1198  
	1199  	if uint64(int(off)) != off {
	1200  		return 0, errors.New("offset out of range")
	1201  	}
	1202  
	1203  	b := makeBuf(d, format, "addr", 0, d.addr)
	1204  	b.skip(int(off))
	1205  	val := b.addr()
	1206  	if b.err != nil {
	1207  		return 0, b.err
	1208  	}
	1209  	return val, nil
	1210  }
	1211  

View as plain text