variables.go 42.9 KB
Newer Older
D
Derek Parker 已提交
1
package proc
2 3 4 5

import (
	"bytes"
	"encoding/binary"
6
	"errors"
7
	"fmt"
8
	"go/constant"
9 10
	"go/parser"
	"go/token"
11
	"math"
12
	"reflect"
13 14 15
	"strings"
	"unsafe"

D
Derek Parker 已提交
16 17
	"github.com/derekparker/delve/pkg/dwarf/op"
	"github.com/derekparker/delve/pkg/dwarf/reader"
18
	"golang.org/x/debug/dwarf"
19 20
)

21
const (
22
	maxErrCount = 3 // Max number of read errors to accept while evaluating slices, arrays and structs
23

24
	maxArrayStridePrefetch = 1024 // Maximum size of array stride for which we will prefetch the array contents
25

D
Derek Parker 已提交
26 27
	chanRecv = "chan receive"
	chanSend = "chan send"
A
aarzilli 已提交
28 29 30

	hashTophashEmpty = 0 // used by map reading code, indicates an empty bucket
	hashMinTopHash   = 4 // used by map reading code, indicates minimum value of tophash that isn't empty or evacuated
31 32
)

33 34 35 36 37 38 39 40 41
type FloatSpecial uint8

const (
	FloatIsNormal FloatSpecial = iota
	FloatIsNaN
	FloatIsPosInf
	FloatIsNegInf
)

D
Derek Parker 已提交
42 43 44 45
// Variable represents a variable. It contains the address, name,
// type and other information parsed from both the Dwarf information
// and the memory of the debugged process.
// If OnlyAddr is true, the variables value has not been loaded.
46
type Variable struct {
47
	Addr      uintptr
A
aarzilli 已提交
48
	OnlyAddr  bool
49
	Name      string
50 51 52
	DwarfType dwarf.Type
	RealType  dwarf.Type
	Kind      reflect.Kind
53
	mem       MemoryReadWriter
54
	bi        *BinaryInfo
55

56 57
	Value        constant.Value
	FloatSpecial FloatSpecial
58 59 60 61

	Len int64
	Cap int64

62 63
	// Base address of arrays, Base address of the backing array for slices (0 for nil slices)
	// Base address of the backing byte array for strings
A
aarzilli 已提交
64
	// address of the struct backing chan and map variables
A
aarzilli 已提交
65
	// address of the function entry point for function variables (0 for nil function pointers)
66
	Base      uintptr
67 68
	stride    int64
	fieldType dwarf.Type
69

A
aarzilli 已提交
70 71 72
	// number of elements to skip when loading a map
	mapSkip int

73 74 75 76
	Children []Variable

	loaded     bool
	Unreadable error
77 78
}

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
type LoadConfig struct {
	// FollowPointers requests pointers to be automatically dereferenced.
	FollowPointers bool
	// MaxVariableRecurse is how far to recurse when evaluating nested types.
	MaxVariableRecurse int
	// MaxStringLen is the maximum number of bytes read from a string
	MaxStringLen int
	// MaxArrayValues is the maximum number of elements read from an array, a slice or a map.
	MaxArrayValues int
	// MaxStructFields is the maximum number of fields read from a struct, -1 will read all fields.
	MaxStructFields int
}

var loadSingleValue = LoadConfig{false, 0, 64, 0, 0}
var loadFullValue = LoadConfig{true, 1, 64, 64, -1}

D
Derek Parker 已提交
95
// G status, from: src/runtime/runtime2.go
96
const (
D
Derek Parker 已提交
97 98 99 100 101 102 103 104 105
	Gidle           uint64 = iota // 0
	Grunnable                     // 1 runnable and on a run queue
	Grunning                      // 2
	Gsyscall                      // 3
	Gwaiting                      // 4
	GmoribundUnused               // 5 currently unused, but hardcoded in gdb scripts
	Gdead                         // 6
	Genqueue                      // 7 Only the Gscanenqueue is used.
	Gcopystack                    // 8 in this state when newstack is moving the stack
106 107
)

D
Derek Parker 已提交
108
// G represents a runtime G (goroutine) structure (at least the
109
// fields that Delve is interested in).
D
Derek Parker 已提交
110
type G struct {
D
Derek Parker 已提交
111
	ID         int    // Goroutine ID
112 113 114 115
	PC         uint64 // PC of goroutine when it was parked.
	SP         uint64 // SP of goroutine when it was parked.
	GoPC       uint64 // PC of 'go' statement that created this goroutine.
	WaitReason string // Reason for goroutine being parked.
116
	Status     uint64
A
Alessandro Arzilli 已提交
117 118
	stkbarVar  *Variable // stkbar field of g struct
	stkbarPos  int       // stkbarPos field of g struct
119
	stackhi    uint64    // value of stack.hi
120

121
	// Information on goroutine location
122
	CurrentLoc Location
123

A
aarzilli 已提交
124
	// Thread that this goroutine is currently allocated to
125
	Thread Thread
126

A
Alessandro Arzilli 已提交
127
	variable *Variable
128 129
}

D
Derek Parker 已提交
130 131
// EvalScope is the scope for variable evaluation. Contains the thread,
// current location (PC), and canonical frame address.
132
type EvalScope struct {
133 134 135 136 137
	PC      uint64           // Current instruction of the evaluation frame
	CFA     int64            // Stack address of the evaluation frame
	Mem     MemoryReadWriter // Target's memory
	Gvar    *Variable
	BinInfo *BinaryInfo
138
	StackHi uint64
139 140
}

D
Derek Parker 已提交
141
// IsNilErr is returned when a variable is nil.
142 143 144 145 146 147 148 149
type IsNilErr struct {
	name string
}

func (err *IsNilErr) Error() string {
	return fmt.Sprintf("%s is nil", err.name)
}

150
func (scope *EvalScope) newVariable(name string, addr uintptr, dwarfType dwarf.Type) *Variable {
151
	return newVariable(name, addr, dwarfType, scope.BinInfo, scope.Mem)
152 153
}

154
func newVariableFromThread(t Thread, name string, addr uintptr, dwarfType dwarf.Type) *Variable {
155
	return newVariable(name, addr, dwarfType, t.BinInfo(), t)
156 157
}

158
func (v *Variable) newVariable(name string, addr uintptr, dwarfType dwarf.Type) *Variable {
159
	return newVariable(name, addr, dwarfType, v.bi, v.mem)
160 161
}

162
func newVariable(name string, addr uintptr, dwarfType dwarf.Type, bi *BinaryInfo, mem MemoryReadWriter) *Variable {
163 164 165
	v := &Variable{
		Name:      name,
		Addr:      addr,
166
		DwarfType: dwarfType,
167
		mem:       mem,
168
		bi:        bi,
169 170
	}

171
	v.RealType = resolveTypedef(v.DwarfType)
172 173 174

	switch t := v.RealType.(type) {
	case *dwarf.PtrType:
175 176 177
		v.Kind = reflect.Ptr
		if _, isvoid := t.Type.(*dwarf.VoidType); isvoid {
			v.Kind = reflect.UnsafePointer
178
		}
179 180 181 182 183 184 185 186 187
	case *dwarf.ChanType:
		v.Kind = reflect.Chan
	case *dwarf.MapType:
		v.Kind = reflect.Map
	case *dwarf.StringType:
		v.Kind = reflect.String
		v.stride = 1
		v.fieldType = &dwarf.UintType{BasicType: dwarf.BasicType{CommonType: dwarf.CommonType{ByteSize: 1, Name: "byte"}, BitSize: 8, BitOffset: 0}}
		if v.Addr != 0 {
188
			v.Base, v.Len, v.Unreadable = readStringInfo(v.mem, v.bi.Arch, v.Addr)
189 190 191 192 193 194 195 196 197 198
		}
	case *dwarf.SliceType:
		v.Kind = reflect.Slice
		if v.Addr != 0 {
			v.loadSliceInfo(t)
		}
	case *dwarf.InterfaceType:
		v.Kind = reflect.Interface
	case *dwarf.StructType:
		v.Kind = reflect.Struct
199
	case *dwarf.ArrayType:
200
		v.Kind = reflect.Array
201
		v.Base = v.Addr
202 203 204 205 206 207 208 209
		v.Len = t.Count
		v.Cap = -1
		v.fieldType = t.Type
		v.stride = 0

		if t.Count > 0 {
			v.stride = t.ByteSize / t.Count
		}
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
	case *dwarf.ComplexType:
		switch t.ByteSize {
		case 8:
			v.Kind = reflect.Complex64
		case 16:
			v.Kind = reflect.Complex128
		}
	case *dwarf.IntType:
		v.Kind = reflect.Int
	case *dwarf.UintType:
		v.Kind = reflect.Uint
	case *dwarf.FloatType:
		switch t.ByteSize {
		case 4:
			v.Kind = reflect.Float32
		case 8:
			v.Kind = reflect.Float64
		}
	case *dwarf.BoolType:
		v.Kind = reflect.Bool
	case *dwarf.FuncType:
		v.Kind = reflect.Func
	case *dwarf.VoidType:
		v.Kind = reflect.Invalid
	case *dwarf.UnspecifiedType:
		v.Kind = reflect.Invalid
	default:
		v.Unreadable = fmt.Errorf("Unknown type: %T", t)
238 239
	}

240 241 242
	return v
}

243 244 245 246 247 248 249 250 251 252
func resolveTypedef(typ dwarf.Type) dwarf.Type {
	for {
		if tt, ok := typ.(*dwarf.TypedefType); ok {
			typ = tt.Type
		} else {
			return typ
		}
	}
}

253
func newConstant(val constant.Value, mem MemoryReadWriter) *Variable {
254
	v := &Variable{Value: val, mem: mem, loaded: true}
A
aarzilli 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
	switch val.Kind() {
	case constant.Int:
		v.Kind = reflect.Int
	case constant.Float:
		v.Kind = reflect.Float64
	case constant.Bool:
		v.Kind = reflect.Bool
	case constant.Complex:
		v.Kind = reflect.Complex128
	case constant.String:
		v.Kind = reflect.String
		v.Len = int64(len(constant.StringVal(val)))
	}
	return v
}

var nilVariable = &Variable{
272
	Name:     "nil",
A
aarzilli 已提交
273
	Addr:     0,
274
	Base:     0,
A
aarzilli 已提交
275 276 277 278
	Kind:     reflect.Ptr,
	Children: []Variable{{Addr: 0, OnlyAddr: true}},
}

279 280 281
func (v *Variable) clone() *Variable {
	r := *v
	return &r
282 283
}

D
Derek Parker 已提交
284 285
// TypeString returns the string representation
// of the type of this variable.
286 287 288 289 290
func (v *Variable) TypeString() string {
	if v == nilVariable {
		return "nil"
	}
	if v.DwarfType != nil {
291
		return v.DwarfType.Common().Name
292 293 294 295
	}
	return v.Kind.String()
}

296
func (v *Variable) toField(field *dwarf.StructField) (*Variable, error) {
297 298 299
	if v.Unreadable != nil {
		return v.clone(), nil
	}
D
Derek Parker 已提交
300
	if v.Addr == 0 {
301
		return nil, &IsNilErr{v.Name}
D
Derek Parker 已提交
302 303
	}

304 305
	name := ""
	if v.Name != "" {
306 307 308 309
		parts := strings.Split(field.Name, ".")
		if len(parts) > 1 {
			name = fmt.Sprintf("%s.%s", v.Name, parts[1])
		} else {
D
Derek Parker 已提交
310
			name = fmt.Sprintf("%s.%s", v.Name, field.Name)
311
		}
312
	}
313
	return v.newVariable(name, uintptr(int64(v.Addr)+field.ByteOffset), field.Type), nil
314 315
}

D
Derek Parker 已提交
316 317
// DwarfReader returns the DwarfReader containing the
// Dwarf information for the target process.
318
func (scope *EvalScope) DwarfReader() *reader.Reader {
319
	return scope.BinInfo.DwarfReader()
320 321
}

D
Derek Parker 已提交
322
// Type returns the Dwarf type entry at `offset`.
323
func (scope *EvalScope) Type(offset dwarf.Offset) (dwarf.Type, error) {
324
	return scope.BinInfo.dwarf.Type(offset)
325 326
}

D
Derek Parker 已提交
327
// PtrSize returns the size of a pointer.
328
func (scope *EvalScope) PtrSize() int {
329
	return scope.BinInfo.Arch.PtrSize()
330 331
}

A
aarzilli 已提交
332
// ChanRecvBlocked returns whether the goroutine is blocked on
333
// a channel read operation.
334
func (g *G) ChanRecvBlocked() bool {
335
	return (g.Thread == nil) && (g.WaitReason == chanRecv)
D
Derek Parker 已提交
336 337
}

D
Derek Parker 已提交
338 339
// NoGError returned when a G could not be found
// for a specific thread.
340 341 342 343 344 345 346 347
type NoGError struct {
	tid int
}

func (ng NoGError) Error() string {
	return fmt.Sprintf("no G executing on thread %d", ng.tid)
}

348 349 350 351 352
func (gvar *Variable) parseG() (*G, error) {
	mem := gvar.mem
	gaddr := uint64(gvar.Addr)
	_, deref := gvar.RealType.(*dwarf.PtrType)

353
	if deref {
354
		gaddrbytes := make([]byte, gvar.bi.Arch.PtrSize())
355
		_, err := mem.ReadMemory(gaddrbytes, uintptr(gaddr))
356 357 358 359
		if err != nil {
			return nil, fmt.Errorf("error derefing *G %s", err)
		}
		gaddr = binary.LittleEndian.Uint64(gaddrbytes)
360
	}
D
Derek Parker 已提交
361
	if gaddr == 0 {
362
		id := 0
363
		if thread, ok := mem.(Thread); ok {
364
			id = thread.ThreadID()
365
		}
A
Alessandro Arzilli 已提交
366
		return nil, NoGError{tid: id}
367
	}
A
Alessandro Arzilli 已提交
368 369 370 371 372 373
	for {
		if _, isptr := gvar.RealType.(*dwarf.PtrType); !isptr {
			break
		}
		gvar = gvar.maybeDereference()
	}
374
	gvar.loadValue(LoadConfig{false, 2, 64, 0, -1})
D
Derek Parker 已提交
375 376
	if gvar.Unreadable != nil {
		return nil, gvar.Unreadable
377
	}
A
Alessandro Arzilli 已提交
378 379 380 381 382 383
	schedVar := gvar.fieldVariable("sched")
	pc, _ := constant.Int64Val(schedVar.fieldVariable("pc").Value)
	sp, _ := constant.Int64Val(schedVar.fieldVariable("sp").Value)
	id, _ := constant.Int64Val(gvar.fieldVariable("goid").Value)
	gopc, _ := constant.Int64Val(gvar.fieldVariable("gopc").Value)
	waitReason := constant.StringVal(gvar.fieldVariable("waitreason").Value)
384 385 386 387 388 389
	var stackhi uint64
	if stackVar := gvar.fieldVariable("stack"); stackVar != nil {
		if stackhiVar := stackVar.fieldVariable("hi"); stackhiVar != nil {
			stackhi, _ = constant.Uint64Val(stackhiVar.Value)
		}
	}
390

A
Alessandro Arzilli 已提交
391
	stkbarVar, _ := gvar.structMember("stkbar")
392 393 394 395 396 397
	stkbarVarPosFld := gvar.fieldVariable("stkbarPos")
	var stkbarPos int64
	if stkbarVarPosFld != nil { // stack barriers were removed in Go 1.9
		stkbarPos, _ = constant.Int64Val(stkbarVarPosFld.Value)
	}

A
Alessandro Arzilli 已提交
398
	status, _ := constant.Int64Val(gvar.fieldVariable("atomicstatus").Value)
399
	f, l, fn := gvar.bi.PCToLine(uint64(pc))
D
Derek Parker 已提交
400 401 402 403 404 405 406 407
	g := &G{
		ID:         int(id),
		GoPC:       uint64(gopc),
		PC:         uint64(pc),
		SP:         uint64(sp),
		WaitReason: waitReason,
		Status:     uint64(status),
		CurrentLoc: Location{PC: uint64(pc), File: f, Line: l, Fn: fn},
A
Alessandro Arzilli 已提交
408
		variable:   gvar,
A
Alessandro Arzilli 已提交
409 410
		stkbarVar:  stkbarVar,
		stkbarPos:  int(stkbarPos),
411
		stackhi:    stackhi,
412
	}
D
Derek Parker 已提交
413 414
	return g, nil
}
415

A
Alessandro Arzilli 已提交
416
func (v *Variable) loadFieldNamed(name string) *Variable {
D
Derek Parker 已提交
417
	v, err := v.structMember(name)
418
	if err != nil {
D
Derek Parker 已提交
419
		return nil
420
	}
421
	v.loadValue(loadFullValue)
D
Derek Parker 已提交
422 423
	if v.Unreadable != nil {
		return nil
424
	}
D
Derek Parker 已提交
425
	return v
426 427
}

A
Alessandro Arzilli 已提交
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
func (v *Variable) fieldVariable(name string) *Variable {
	for i := range v.Children {
		if child := &v.Children[i]; child.Name == name {
			return child
		}
	}
	return nil
}

// PC of entry to top-most deferred function.
func (g *G) DeferPC() uint64 {
	if g.variable.Unreadable != nil {
		return 0
	}
	d := g.variable.fieldVariable("_defer").maybeDereference()
	if d.Addr == 0 {
		return 0
	}
	d.loadValue(LoadConfig{false, 1, 64, 0, -1})
	if d.Unreadable != nil {
		return 0
	}
	fnvar := d.fieldVariable("fn").maybeDereference()
	if fnvar.Addr == 0 {
		return 0
	}
	fnvar.loadValue(LoadConfig{false, 1, 64, 0, -1})
	if fnvar.Unreadable != nil {
		return 0
	}
	deferPC, _ := constant.Int64Val(fnvar.fieldVariable("fn").Value)
	return uint64(deferPC)
}

462 463 464 465 466 467 468 469
// From $GOROOT/src/runtime/traceback.go:597
// isExportedRuntime reports whether name is an exported runtime function.
// It is only for runtime functions, so ASCII A-Z is fine.
func isExportedRuntime(name string) bool {
	const n = len("runtime.")
	return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z'
}

D
Derek Parker 已提交
470 471
// UserCurrent returns the location the users code is at,
// or was at before entering a runtime function.
472
func (g *G) UserCurrent() Location {
A
aarzilli 已提交
473 474 475
	it, err := g.stackIterator()
	if err != nil {
		return g.CurrentLoc
476 477 478
	}
	for it.Next() {
		frame := it.Frame()
479 480 481 482 483
		if frame.Call.Fn != nil {
			name := frame.Call.Fn.Name
			if (strings.Index(name, ".") >= 0) && (!strings.HasPrefix(name, "runtime.") || isExportedRuntime(name)) {
				return frame.Call
			}
484 485
		}
	}
486
	return g.CurrentLoc
487 488
}

D
Derek Parker 已提交
489 490
// Go returns the location of the 'go' statement
// that spawned this goroutine.
491
func (g *G) Go() Location {
492
	f, l, fn := g.variable.bi.goSymTable.PCToLine(g.GoPC)
493 494 495
	return Location{PC: g.GoPC, File: f, Line: l, Fn: fn}
}

A
Alessandro Arzilli 已提交
496 497
// Returns the list of saved return addresses used by stack barriers
func (g *G) stkbar() ([]savedLR, error) {
498 499 500
	if g.stkbarVar == nil { // stack barriers were removed in Go 1.9
		return nil, nil
	}
A
Alessandro Arzilli 已提交
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
	g.stkbarVar.loadValue(LoadConfig{false, 1, 0, int(g.stkbarVar.Len), 3})
	if g.stkbarVar.Unreadable != nil {
		return nil, fmt.Errorf("unreadable stkbar: %v\n", g.stkbarVar.Unreadable)
	}
	r := make([]savedLR, len(g.stkbarVar.Children))
	for i, child := range g.stkbarVar.Children {
		for _, field := range child.Children {
			switch field.Name {
			case "savedLRPtr":
				ptr, _ := constant.Int64Val(field.Value)
				r[i].ptr = uint64(ptr)
			case "savedLRVal":
				val, _ := constant.Int64Val(field.Value)
				r[i].val = uint64(val)
			}
		}
	}
	return r, nil
}

D
Derek Parker 已提交
521
// EvalVariable returns the value of the given expression (backwards compatibility).
522 523
func (scope *EvalScope) EvalVariable(name string, cfg LoadConfig) (*Variable, error) {
	return scope.EvalExpression(name, cfg)
A
aarzilli 已提交
524
}
525

D
Derek Parker 已提交
526
// SetVariable sets the value of the named variable
A
aarzilli 已提交
527 528
func (scope *EvalScope) SetVariable(name, value string) error {
	t, err := parser.ParseExpr(name)
529
	if err != nil {
A
aarzilli 已提交
530
		return err
531 532
	}

A
aarzilli 已提交
533
	xv, err := scope.evalAST(t)
534
	if err != nil {
A
aarzilli 已提交
535
		return err
536
	}
537

A
aarzilli 已提交
538 539 540 541 542 543 544 545 546
	if xv.Addr == 0 {
		return fmt.Errorf("Can not assign to \"%s\"", name)
	}

	if xv.Unreadable != nil {
		return fmt.Errorf("Expression \"%s\" is unreadable: %v", name, xv.Unreadable)
	}

	t, err = parser.ParseExpr(value)
547 548 549
	if err != nil {
		return err
	}
A
aarzilli 已提交
550 551 552 553 554 555

	yv, err := scope.evalAST(t)
	if err != nil {
		return err
	}

556
	yv.loadValue(loadSingleValue)
A
aarzilli 已提交
557 558 559

	if err := yv.isType(xv.RealType, xv.Kind); err != nil {
		return err
560
	}
A
aarzilli 已提交
561 562 563 564 565 566

	if yv.Unreadable != nil {
		return fmt.Errorf("Expression \"%s\" is unreadable: %v", value, yv.Unreadable)
	}

	return xv.setValue(yv)
567 568
}

569
func (scope *EvalScope) extractVariableFromEntry(entry *dwarf.Entry, cfg LoadConfig) (*Variable, error) {
570
	rdr := scope.DwarfReader()
571
	v, err := scope.extractVarInfoFromEntry(entry, rdr)
572
	if err != nil {
D
Derek Parker 已提交
573 574
		return nil, err
	}
575
	return v, nil
576
}
D
Derek Parker 已提交
577

578 579
func (scope *EvalScope) extractVarInfo(varName string) (*Variable, error) {
	reader := scope.DwarfReader()
580
	off, err := scope.BinInfo.findFunctionDebugInfo(scope.PC)
581 582
	if err != nil {
		return nil, err
583
	}
A
Alessandro Arzilli 已提交
584 585
	reader.Seek(off)
	reader.Next()
586

587
	for entry, err := reader.NextScopeVariable(); entry != nil; entry, err = reader.NextScopeVariable() {
D
Derek Parker 已提交
588
		if err != nil {
589
			return nil, err
D
Derek Parker 已提交
590
		}
A
Alessandro Arzilli 已提交
591 592 593
		if entry.Tag == 0 {
			break
		}
D
Derek Parker 已提交
594 595 596 597 598 599

		n, ok := entry.Val(dwarf.AttrName).(string)
		if !ok {
			continue
		}

600
		if n == varName {
601
			return scope.extractVarInfoFromEntry(entry, reader)
D
Derek Parker 已提交
602 603
		}
	}
604
	return nil, fmt.Errorf("could not find symbol value for %s", varName)
D
Derek Parker 已提交
605
}
606

607
// LocalVariables returns all local variables from the current function scope.
608 609
func (scope *EvalScope) LocalVariables(cfg LoadConfig) ([]*Variable, error) {
	return scope.variablesByTag(dwarf.TagVariable, cfg)
610 611 612
}

// FunctionArguments returns the name, value, and type of all current function arguments.
613 614
func (scope *EvalScope) FunctionArguments(cfg LoadConfig) ([]*Variable, error) {
	return scope.variablesByTag(dwarf.TagFormalParameter, cfg)
615 616 617
}

// PackageVariables returns the name, value, and type of all package variables in the application.
618
func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) {
D
Derek Parker 已提交
619
	var vars []*Variable
620
	reader := scope.DwarfReader()
621

622 623 624 625 626 627
	var utypoff dwarf.Offset
	utypentry, err := reader.SeekToTypeNamed("<unspecified>")
	if err == nil {
		utypoff = utypentry.Offset
	}

628 629 630 631 632
	for entry, err := reader.NextPackageVariable(); entry != nil; entry, err = reader.NextPackageVariable() {
		if err != nil {
			return nil, err
		}

633 634 635 636
		if typoff, ok := entry.Val(dwarf.AttrType).(dwarf.Offset); !ok || typoff == utypoff {
			continue
		}

637
		// Ignore errors trying to extract values
638
		val, err := scope.extractVariableFromEntry(entry, cfg)
639 640 641
		if err != nil {
			continue
		}
A
Alessandro Arzilli 已提交
642
		val.loadValue(cfg)
643 644 645 646 647 648
		vars = append(vars, val)
	}

	return vars, nil
}

649 650
func (scope *EvalScope) packageVarAddr(name string) (*Variable, error) {
	reader := scope.DwarfReader()
651 652 653 654 655 656 657 658 659 660
	for entry, err := reader.NextPackageVariable(); entry != nil; entry, err = reader.NextPackageVariable() {
		if err != nil {
			return nil, err
		}

		n, ok := entry.Val(dwarf.AttrName).(string)
		if !ok {
			continue
		}

661
		if n == name || strings.HasSuffix(n, "/"+name) {
662
			return scope.extractVarInfoFromEntry(entry, reader)
663 664 665 666 667
		}
	}
	return nil, fmt.Errorf("could not find symbol value for %s", name)
}

668
func (v *Variable) structMember(memberName string) (*Variable, error) {
669 670 671 672
	if v.Unreadable != nil {
		return v.clone(), nil
	}
	structVar := v.maybeDereference()
673
	structVar.Name = v.Name
674 675
	if structVar.Unreadable != nil {
		return structVar, nil
676
	}
677 678

	switch t := structVar.RealType.(type) {
679 680 681 682
	case *dwarf.StructType:
		for _, field := range t.Field {
			if field.Name != memberName {
				continue
683
			}
L
Luke Hoban 已提交
684
			return structVar.toField(field)
685 686 687 688 689
		}
		// Check for embedded field only if field was
		// not a regular struct member
		for _, field := range t.Field {
			isEmbeddedStructMember :=
690
				(field.Type.Common().Name == field.Name) ||
D
Derek Parker 已提交
691 692
					(len(field.Name) > 1 &&
						field.Name[0] == '*' &&
693
						field.Type.Common().Name[1:] == field.Name[1:])
694 695 696 697 698 699
			if !isEmbeddedStructMember {
				continue
			}
			// Check for embedded field referenced by type name
			parts := strings.Split(field.Name, ".")
			if len(parts) > 1 && parts[1] == memberName {
L
Luke Hoban 已提交
700
				embeddedVar, err := structVar.toField(field)
701 702 703 704 705 706
				if err != nil {
					return nil, err
				}
				return embeddedVar, nil
			}
			// Recursively check for promoted fields on the embedded field
L
Luke Hoban 已提交
707
			embeddedVar, err := structVar.toField(field)
708 709 710 711 712 713 714
			if err != nil {
				return nil, err
			}
			embeddedVar.Name = structVar.Name
			embeddedField, err := embeddedVar.structMember(memberName)
			if embeddedField != nil {
				return embeddedField, nil
715 716
			}
		}
717 718
		return nil, fmt.Errorf("%s has no member %s", v.Name, memberName)
	default:
719 720 721
		if v.Name == "" {
			return nil, fmt.Errorf("type %s is not a struct", structVar.TypeString())
		}
D
Derek Parker 已提交
722
		return nil, fmt.Errorf("%s (type %s) is not a struct", v.Name, structVar.TypeString())
723
	}
724 725
}

726 727 728
// Extracts the name and type of a variable from a dwarf entry
// then executes the instructions given in the  DW_AT_location attribute to grab the variable's address
func (scope *EvalScope) extractVarInfoFromEntry(entry *dwarf.Entry, rdr *reader.Reader) (*Variable, error) {
E
epipho 已提交
729
	if entry == nil {
D
Derek Parker 已提交
730
		return nil, fmt.Errorf("invalid entry")
E
epipho 已提交
731 732 733 734 735 736 737 738
	}

	if entry.Tag != dwarf.TagFormalParameter && entry.Tag != dwarf.TagVariable {
		return nil, fmt.Errorf("invalid entry tag, only supports FormalParameter and Variable, got %s", entry.Tag.String())
	}

	n, ok := entry.Val(dwarf.AttrName).(string)
	if !ok {
D
Derek Parker 已提交
739
		return nil, fmt.Errorf("type assertion failed")
E
epipho 已提交
740 741 742 743
	}

	offset, ok := entry.Val(dwarf.AttrType).(dwarf.Offset)
	if !ok {
D
Derek Parker 已提交
744
		return nil, fmt.Errorf("type assertion failed")
E
epipho 已提交
745 746
	}

747
	t, err := scope.Type(offset)
E
epipho 已提交
748 749 750 751 752 753
	if err != nil {
		return nil, err
	}

	instructions, ok := entry.Val(dwarf.AttrLocation).([]byte)
	if !ok {
D
Derek Parker 已提交
754
		return nil, fmt.Errorf("type assertion failed")
E
epipho 已提交
755 756
	}

757
	addr, err := op.ExecuteStackProgram(scope.CFA, instructions)
E
epipho 已提交
758 759 760 761
	if err != nil {
		return nil, err
	}

762
	return scope.newVariable(n, uintptr(addr), t), nil
E
epipho 已提交
763 764
}

765
// If v is a pointer a new variable is returned containing the value pointed by v.
766 767 768 769
func (v *Variable) maybeDereference() *Variable {
	if v.Unreadable != nil {
		return v
	}
770

771
	switch t := v.RealType.(type) {
772
	case *dwarf.PtrType:
773 774
		ptrval, err := readUintRaw(v.mem, uintptr(v.Addr), t.ByteSize)
		r := v.newVariable("", uintptr(ptrval), t.Type)
775
		if err != nil {
776
			r.Unreadable = err
777 778
		}

779
		return r
780
	default:
781
		return v
782 783
	}
}
784

785
// Extracts the value of the variable at the given address.
786 787
func (v *Variable) loadValue(cfg LoadConfig) {
	v.loadValueInternal(0, cfg)
788 789
}

790
func (v *Variable) loadValueInternal(recurseLevel int, cfg LoadConfig) {
791
	if v.Unreadable != nil || v.loaded || (v.Addr == 0 && v.Base == 0) {
792 793
		return
	}
794

795 796
	v.loaded = true
	switch v.Kind {
A
aarzilli 已提交
797
	case reflect.Ptr, reflect.UnsafePointer:
798 799
		v.Len = 1
		v.Children = []Variable{*v.maybeDereference()}
800 801
		if cfg.FollowPointers {
			// Don't increase the recursion level when dereferencing pointers
802 803 804 805 806 807
			// unless this is a pointer to interface (which could cause an infinite loop)
			nextLvl := recurseLevel
			if v.Children[0].Kind == reflect.Interface {
				nextLvl++
			}
			v.Children[0].loadValueInternal(nextLvl, cfg)
808 809 810
		} else {
			v.Children[0].OnlyAddr = true
		}
811

A
aarzilli 已提交
812
	case reflect.Chan:
813 814 815
		sv := v.clone()
		sv.RealType = resolveTypedef(&(sv.RealType.(*dwarf.ChanType).TypedefType))
		sv = sv.maybeDereference()
816
		sv.loadValueInternal(0, loadFullValue)
A
aarzilli 已提交
817 818
		v.Children = sv.Children
		v.Len = sv.Len
819
		v.Base = sv.Addr
A
aarzilli 已提交
820

A
aarzilli 已提交
821
	case reflect.Map:
822 823
		if recurseLevel <= cfg.MaxVariableRecurse {
			v.loadMap(recurseLevel, cfg)
A
aarzilli 已提交
824
		}
A
aarzilli 已提交
825

826
	case reflect.String:
827
		var val string
828
		val, v.Unreadable = readStringValue(v.mem, v.Base, v.Len, cfg)
829
		v.Value = constant.MakeString(val)
830 831

	case reflect.Slice, reflect.Array:
832
		v.loadArrayValues(recurseLevel, cfg)
833 834

	case reflect.Struct:
835
		v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size()))
836 837 838 839
		t := v.RealType.(*dwarf.StructType)
		v.Len = int64(len(t.Field))
		// Recursively call extractValue to grab
		// the value of all the members of the struct.
840
		if recurseLevel <= cfg.MaxVariableRecurse {
841 842
			v.Children = make([]Variable, 0, len(t.Field))
			for i, field := range t.Field {
843 844 845
				if cfg.MaxStructFields >= 0 && len(v.Children) >= cfg.MaxStructFields {
					break
				}
846 847 848
				f, _ := v.toField(field)
				v.Children = append(v.Children, *f)
				v.Children[i].Name = field.Name
849
				v.Children[i].loadValueInternal(recurseLevel+1, cfg)
850
			}
851 852
		}

853
	case reflect.Interface:
854
		v.loadInterface(recurseLevel, true, cfg)
855

856 857 858
	case reflect.Complex64, reflect.Complex128:
		v.readComplex(v.RealType.(*dwarf.ComplexType).ByteSize)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
859
		var val int64
860
		val, v.Unreadable = readIntRaw(v.mem, v.Addr, v.RealType.(*dwarf.IntType).ByteSize)
861
		v.Value = constant.MakeInt64(val)
862
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
863
		var val uint64
864
		val, v.Unreadable = readUintRaw(v.mem, v.Addr, v.RealType.(*dwarf.UintType).ByteSize)
865 866
		v.Value = constant.MakeUint64(val)

867
	case reflect.Bool:
868 869
		val := make([]byte, 1)
		_, err := v.mem.ReadMemory(val, v.Addr)
870 871
		v.Unreadable = err
		if err == nil {
872
			v.Value = constant.MakeBool(val[0] != 0)
873
		}
874
	case reflect.Float32, reflect.Float64:
875 876 877
		var val float64
		val, v.Unreadable = v.readFloatRaw(v.RealType.(*dwarf.FloatType).ByteSize)
		v.Value = constant.MakeFloat64(val)
878 879 880 881 882 883 884 885
		switch {
		case math.IsInf(val, +1):
			v.FloatSpecial = FloatIsPosInf
		case math.IsInf(val, -1):
			v.FloatSpecial = FloatIsNegInf
		case math.IsNaN(val):
			v.FloatSpecial = FloatIsNaN
		}
886 887
	case reflect.Func:
		v.readFunctionPtr()
888
	default:
889
		v.Unreadable = fmt.Errorf("unknown or unsupported kind: \"%s\"", v.Kind.String())
890 891 892
	}
}

A
aarzilli 已提交
893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
func (v *Variable) setValue(y *Variable) error {
	var err error
	switch v.Kind {
	case reflect.Float32, reflect.Float64:
		f, _ := constant.Float64Val(y.Value)
		err = v.writeFloatRaw(f, v.RealType.Size())
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		n, _ := constant.Int64Val(y.Value)
		err = v.writeUint(uint64(n), v.RealType.Size())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		n, _ := constant.Uint64Val(y.Value)
		err = v.writeUint(n, v.RealType.Size())
	case reflect.Bool:
		err = v.writeBool(constant.BoolVal(y.Value))
	case reflect.Complex64, reflect.Complex128:
		real, _ := constant.Float64Val(constant.Real(y.Value))
		imag, _ := constant.Float64Val(constant.Imag(y.Value))
		err = v.writeComplex(real, imag, v.RealType.Size())
911
	default:
912 913
		if t, isptr := v.RealType.(*dwarf.PtrType); isptr {
			err = v.writeUint(uint64(y.Children[0].Addr), int64(t.ByteSize))
A
aarzilli 已提交
914 915 916
		} else {
			return fmt.Errorf("can not set variables of type %s (not implemented)", v.Kind.String())
		}
917
	}
A
aarzilli 已提交
918 919

	return err
920 921
}

922
func readStringInfo(mem MemoryReadWriter, arch Arch, addr uintptr) (uintptr, int64, error) {
923 924 925
	// string data structure is always two ptrs in size. Addr, followed by len
	// http://research.swtch.com/godata

926 927
	mem = cacheMemory(mem, addr, arch.PtrSize()*2)

928
	// read len
929 930
	val := make([]byte, arch.PtrSize())
	_, err := mem.ReadMemory(val, addr+uintptr(arch.PtrSize()))
931
	if err != nil {
A
aarzilli 已提交
932
		return 0, 0, fmt.Errorf("could not read string len %s", err)
933
	}
934
	strlen := int64(binary.LittleEndian.Uint64(val))
935
	if strlen < 0 {
A
aarzilli 已提交
936
		return 0, 0, fmt.Errorf("invalid length: %d", strlen)
937
	}
938 939

	// read addr
940
	_, err = mem.ReadMemory(val, addr)
941
	if err != nil {
A
aarzilli 已提交
942
		return 0, 0, fmt.Errorf("could not read string pointer %s", err)
943 944
	}
	addr = uintptr(binary.LittleEndian.Uint64(val))
D
Derek Parker 已提交
945
	if addr == 0 {
A
aarzilli 已提交
946
		return 0, 0, nil
D
Derek Parker 已提交
947
	}
D
Derek Parker 已提交
948

A
aarzilli 已提交
949 950 951
	return addr, strlen, nil
}

952
func readStringValue(mem MemoryReadWriter, addr uintptr, strlen int64, cfg LoadConfig) (string, error) {
A
aarzilli 已提交
953
	count := strlen
954 955
	if count > int64(cfg.MaxStringLen) {
		count = int64(cfg.MaxStringLen)
A
aarzilli 已提交
956 957
	}

958 959
	val := make([]byte, int(count))
	_, err := mem.ReadMemory(val, addr)
960
	if err != nil {
A
aarzilli 已提交
961
		return "", fmt.Errorf("could not read string at %#v due to %s", addr, err)
962 963
	}

964 965
	retstr := *(*string)(unsafe.Pointer(&val))

A
aarzilli 已提交
966 967 968
	return retstr, nil
}

969
func (v *Variable) loadSliceInfo(t *dwarf.SliceType) {
970 971
	v.mem = cacheMemory(v.mem, v.Addr, int(t.Size()))

972
	var err error
E
epipho 已提交
973 974 975
	for _, f := range t.Field {
		switch f.Name {
		case "array":
976
			var base uint64
977
			base, err = readUintRaw(v.mem, uintptr(int64(v.Addr)+f.ByteOffset), f.Type.Size())
978
			if err == nil {
979
				v.Base = uintptr(base)
980 981 982
				// Dereference array type to get value type
				ptrType, ok := f.Type.(*dwarf.PtrType)
				if !ok {
983 984
					v.Unreadable = fmt.Errorf("Invalid type %s in slice array", f.Type)
					return
985 986
				}
				v.fieldType = ptrType.Type
E
epipho 已提交
987 988
			}
		case "len":
989
			lstrAddr, _ := v.toField(f)
990
			lstrAddr.loadValue(loadSingleValue)
991
			err = lstrAddr.Unreadable
992
			if err == nil {
993
				v.Len, _ = constant.Int64Val(lstrAddr.Value)
E
epipho 已提交
994 995
			}
		case "cap":
996
			cstrAddr, _ := v.toField(f)
997
			cstrAddr.loadValue(loadSingleValue)
998
			err = cstrAddr.Unreadable
999
			if err == nil {
1000
				v.Cap, _ = constant.Int64Val(cstrAddr.Value)
E
epipho 已提交
1001 1002
			}
		}
1003 1004 1005 1006
		if err != nil {
			v.Unreadable = err
			return
		}
1007 1008
	}

1009
	v.stride = v.fieldType.Size()
1010 1011
	if t, ok := v.fieldType.(*dwarf.PtrType); ok {
		v.stride = t.ByteSize
1012
	}
1013

1014
	return
1015 1016
}

1017
func (v *Variable) loadArrayValues(recurseLevel int, cfg LoadConfig) {
1018 1019 1020
	if v.Unreadable != nil {
		return
	}
1021 1022 1023 1024
	if v.Len < 0 {
		v.Unreadable = errors.New("Negative array length")
		return
	}
1025

1026 1027
	count := v.Len
	// Cap number of elements
1028 1029
	if count > int64(cfg.MaxArrayValues) {
		count = int64(cfg.MaxArrayValues)
1030
	}
1031

1032
	if v.stride < maxArrayStridePrefetch {
1033
		v.mem = cacheMemory(v.mem, v.Base, int(v.stride*count))
1034
	}
1035

1036 1037 1038
	errcount := 0

	for i := int64(0); i < count; i++ {
1039
		fieldvar := v.newVariable("", uintptr(int64(v.Base)+(i*v.stride)), v.fieldType)
1040
		fieldvar.loadValueInternal(recurseLevel+1, cfg)
1041 1042

		if fieldvar.Unreadable != nil {
1043
			errcount++
E
epipho 已提交
1044
		}
1045

1046
		v.Children = append(v.Children, *fieldvar)
1047 1048 1049
		if errcount > maxErrCount {
			break
		}
1050 1051 1052
	}
}

1053
func (v *Variable) readComplex(size int64) {
1054 1055 1056 1057 1058 1059 1060
	var fs int64
	switch size {
	case 8:
		fs = 4
	case 16:
		fs = 8
	default:
1061 1062
		v.Unreadable = fmt.Errorf("invalid size (%d) for complex type", size)
		return
1063
	}
1064 1065 1066

	ftyp := &dwarf.FloatType{BasicType: dwarf.BasicType{CommonType: dwarf.CommonType{ByteSize: fs, Name: fmt.Sprintf("float%d", fs)}, BitSize: fs * 8, BitOffset: 0}}

1067 1068
	realvar := v.newVariable("real", v.Addr, ftyp)
	imagvar := v.newVariable("imaginary", v.Addr+uintptr(fs), ftyp)
1069 1070
	realvar.loadValue(loadSingleValue)
	imagvar.loadValue(loadSingleValue)
A
aarzilli 已提交
1071
	v.Value = constant.BinaryOp(realvar.Value, token.ADD, constant.MakeImag(imagvar.Value))
1072 1073
}

A
aarzilli 已提交
1074 1075
func (v *Variable) writeComplex(real, imag float64, size int64) error {
	err := v.writeFloatRaw(real, int64(size/2))
1076 1077 1078 1079 1080 1081 1082 1083
	if err != nil {
		return err
	}
	imagaddr := *v
	imagaddr.Addr += uintptr(size / 2)
	return imagaddr.writeFloatRaw(imag, int64(size/2))
}

1084
func readIntRaw(mem MemoryReadWriter, addr uintptr, size int64) (int64, error) {
E
epipho 已提交
1085
	var n int64
1086

1087 1088
	val := make([]byte, int(size))
	_, err := mem.ReadMemory(val, addr)
1089
	if err != nil {
D
Derek Parker 已提交
1090
		return 0, err
1091 1092
	}

1093 1094
	switch size {
	case 1:
1095
		n = int64(int8(val[0]))
1096
	case 2:
1097
		n = int64(int16(binary.LittleEndian.Uint16(val)))
1098
	case 4:
1099
		n = int64(int32(binary.LittleEndian.Uint32(val)))
1100
	case 8:
E
epipho 已提交
1101
		n = int64(binary.LittleEndian.Uint64(val))
1102
	}
1103

D
Derek Parker 已提交
1104
	return n, nil
E
epipho 已提交
1105 1106
}

A
aarzilli 已提交
1107
func (v *Variable) writeUint(value uint64, size int64) error {
1108 1109 1110 1111
	val := make([]byte, size)

	switch size {
	case 1:
A
aarzilli 已提交
1112
		val[0] = byte(value)
1113
	case 2:
A
aarzilli 已提交
1114
		binary.LittleEndian.PutUint16(val, uint16(value))
1115
	case 4:
A
aarzilli 已提交
1116
		binary.LittleEndian.PutUint32(val, uint32(value))
1117
	case 8:
A
aarzilli 已提交
1118
		binary.LittleEndian.PutUint64(val, uint64(value))
1119 1120
	}

1121
	_, err := v.mem.WriteMemory(v.Addr, val)
1122 1123 1124
	return err
}

1125
func readUintRaw(mem MemoryReadWriter, addr uintptr, size int64) (uint64, error) {
E
epipho 已提交
1126 1127
	var n uint64

1128 1129
	val := make([]byte, int(size))
	_, err := mem.ReadMemory(val, addr)
E
epipho 已提交
1130
	if err != nil {
D
Derek Parker 已提交
1131
		return 0, err
E
epipho 已提交
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
	}

	switch size {
	case 1:
		n = uint64(val[0])
	case 2:
		n = uint64(binary.LittleEndian.Uint16(val))
	case 4:
		n = uint64(binary.LittleEndian.Uint32(val))
	case 8:
		n = uint64(binary.LittleEndian.Uint64(val))
	}

D
Derek Parker 已提交
1145
	return n, nil
1146 1147
}

1148
func (v *Variable) readFloatRaw(size int64) (float64, error) {
1149 1150
	val := make([]byte, int(size))
	_, err := v.mem.ReadMemory(val, v.Addr)
1151
	if err != nil {
1152
		return 0.0, err
1153 1154 1155
	}
	buf := bytes.NewBuffer(val)

D
Derek Parker 已提交
1156 1157 1158 1159
	switch size {
	case 4:
		n := float32(0)
		binary.Read(buf, binary.LittleEndian, &n)
1160
		return float64(n), nil
D
Derek Parker 已提交
1161 1162 1163
	case 8:
		n := float64(0)
		binary.Read(buf, binary.LittleEndian, &n)
1164
		return n, nil
D
Derek Parker 已提交
1165 1166
	}

1167
	return 0.0, fmt.Errorf("could not read float")
1168 1169
}

1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181
func (v *Variable) writeFloatRaw(f float64, size int64) error {
	buf := bytes.NewBuffer(make([]byte, 0, size))

	switch size {
	case 4:
		n := float32(f)
		binary.Write(buf, binary.LittleEndian, n)
	case 8:
		n := float64(f)
		binary.Write(buf, binary.LittleEndian, n)
	}

1182
	_, err := v.mem.WriteMemory(v.Addr, buf.Bytes())
1183 1184 1185
	return err
}

A
aarzilli 已提交
1186
func (v *Variable) writeBool(value bool) error {
1187
	val := []byte{0}
A
aarzilli 已提交
1188
	val[0] = *(*byte)(unsafe.Pointer(&value))
1189
	_, err := v.mem.WriteMemory(v.Addr, val)
1190 1191 1192
	return err
}

1193
func (v *Variable) readFunctionPtr() {
1194
	val := make([]byte, v.bi.Arch.PtrSize())
1195
	_, err := v.mem.ReadMemory(val, v.Addr)
1196
	if err != nil {
1197 1198
		v.Unreadable = err
		return
1199 1200 1201
	}

	// dereference pointer to find function pc
1202 1203
	fnaddr := uintptr(binary.LittleEndian.Uint64(val))
	if fnaddr == 0 {
1204
		v.Base = 0
A
aarzilli 已提交
1205
		v.Value = constant.MakeString("")
1206
		return
1207
	}
1208

1209
	_, err = v.mem.ReadMemory(val, fnaddr)
1210
	if err != nil {
1211 1212
		v.Unreadable = err
		return
1213 1214
	}

1215
	v.Base = uintptr(binary.LittleEndian.Uint64(val))
1216
	fn := v.bi.goSymTable.PCToFunc(uint64(v.Base))
1217
	if fn == nil {
1218
		v.Unreadable = fmt.Errorf("could not find function for %#v", v.Base)
1219
		return
1220 1221
	}

1222
	v.Value = constant.MakeString(fn.Name)
1223 1224
}

1225
func (v *Variable) loadMap(recurseLevel int, cfg LoadConfig) {
A
aarzilli 已提交
1226 1227 1228 1229 1230 1231 1232
	it := v.mapIterator()
	if it == nil {
		return
	}

	for skip := 0; skip < v.mapSkip; skip++ {
		if ok := it.next(); !ok {
1233
			v.Unreadable = fmt.Errorf("map index out of bounds")
A
aarzilli 已提交
1234 1235 1236 1237 1238 1239 1240
			return
		}
	}

	count := 0
	errcount := 0
	for it.next() {
1241
		if count >= cfg.MaxArrayValues {
A
aarzilli 已提交
1242 1243 1244 1245
			break
		}
		key := it.key()
		val := it.value()
1246 1247
		key.loadValueInternal(recurseLevel+1, cfg)
		val.loadValueInternal(recurseLevel+1, cfg)
A
aarzilli 已提交
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278
		if key.Unreadable != nil || val.Unreadable != nil {
			errcount++
		}
		v.Children = append(v.Children, *key)
		v.Children = append(v.Children, *val)
		count++
		if errcount > maxErrCount {
			break
		}
	}
}

type mapIterator struct {
	v          *Variable
	numbuckets uint64
	oldmask    uint64
	buckets    *Variable
	oldbuckets *Variable
	b          *Variable
	bidx       uint64

	tophashes *Variable
	keys      *Variable
	values    *Variable
	overflow  *Variable

	idx int64
}

// Code derived from go/src/runtime/hashmap.go
func (v *Variable) mapIterator() *mapIterator {
1279 1280 1281
	sv := v.clone()
	sv.RealType = resolveTypedef(&(sv.RealType.(*dwarf.MapType).TypedefType))
	sv = sv.maybeDereference()
1282
	v.Base = sv.Addr
A
aarzilli 已提交
1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296

	maptype, ok := sv.RealType.(*dwarf.StructType)
	if !ok {
		v.Unreadable = fmt.Errorf("wrong real type for map")
		return nil
	}

	it := &mapIterator{v: v, bidx: 0, b: nil, idx: 0}

	if sv.Addr == 0 {
		it.numbuckets = 0
		return it
	}

1297
	v.mem = cacheMemory(v.mem, v.Base, int(v.RealType.Size()))
1298

A
aarzilli 已提交
1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320
	for _, f := range maptype.Field {
		var err error
		field, _ := sv.toField(f)
		switch f.Name {
		case "count":
			v.Len, err = field.asInt()
		case "B":
			var b uint64
			b, err = field.asUint()
			it.numbuckets = 1 << b
			it.oldmask = (1 << (b - 1)) - 1
		case "buckets":
			it.buckets = field.maybeDereference()
		case "oldbuckets":
			it.oldbuckets = field.maybeDereference()
		}
		if err != nil {
			v.Unreadable = err
			return nil
		}
	}

1321 1322 1323 1324 1325
	if it.buckets.Kind != reflect.Struct || it.oldbuckets.Kind != reflect.Struct {
		v.Unreadable = mapBucketsNotStructErr
		return nil
	}

A
aarzilli 已提交
1326 1327 1328
	return it
}

1329 1330 1331 1332
var mapBucketContentsNotArrayErr = errors.New("malformed map type: keys, values or tophash of a bucket is not an array")
var mapBucketContentsInconsistentLenErr = errors.New("malformed map type: inconsistent array length in bucket")
var mapBucketsNotStructErr = errors.New("malformed map type: buckets, oldbuckets or overflow field not a struct")

A
aarzilli 已提交
1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383
func (it *mapIterator) nextBucket() bool {
	if it.overflow != nil && it.overflow.Addr > 0 {
		it.b = it.overflow
	} else {
		it.b = nil

		for it.bidx < it.numbuckets {
			it.b = it.buckets.clone()
			it.b.Addr += uintptr(uint64(it.buckets.DwarfType.Size()) * it.bidx)

			if it.oldbuckets.Addr <= 0 {
				break
			}

			// if oldbuckets is not nil we are iterating through a map that is in
			// the middle of a grow.
			// if the bucket we are looking at hasn't been filled in we iterate
			// instead through its corresponding "oldbucket" (i.e. the bucket the
			// elements of this bucket are coming from) but only if this is the first
			// of the two buckets being created from the same oldbucket (otherwise we
			// would print some keys twice)

			oldbidx := it.bidx & it.oldmask
			oldb := it.oldbuckets.clone()
			oldb.Addr += uintptr(uint64(it.oldbuckets.DwarfType.Size()) * oldbidx)

			if mapEvacuated(oldb) {
				break
			}

			if oldbidx == it.bidx {
				it.b = oldb
				break
			}

			// oldbucket origin for current bucket has not been evacuated but we have already
			// iterated over it so we should just skip it
			it.b = nil
			it.bidx++
		}

		if it.b == nil {
			return false
		}
		it.bidx++
	}

	if it.b.Addr <= 0 {
		return false
	}

1384 1385
	it.b.mem = cacheMemory(it.b.mem, it.b.Addr, int(it.b.RealType.Size()))

A
aarzilli 已提交
1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420
	it.tophashes = nil
	it.keys = nil
	it.values = nil
	it.overflow = nil

	for _, f := range it.b.DwarfType.(*dwarf.StructType).Field {
		field, err := it.b.toField(f)
		if err != nil {
			it.v.Unreadable = err
			return false
		}
		if field.Unreadable != nil {
			it.v.Unreadable = field.Unreadable
			return false
		}

		switch f.Name {
		case "tophash":
			it.tophashes = field
		case "keys":
			it.keys = field
		case "values":
			it.values = field
		case "overflow":
			it.overflow = field.maybeDereference()
		}
	}

	// sanity checks
	if it.tophashes == nil || it.keys == nil || it.values == nil {
		it.v.Unreadable = fmt.Errorf("malformed map type")
		return false
	}

	if it.tophashes.Kind != reflect.Array || it.keys.Kind != reflect.Array || it.values.Kind != reflect.Array {
1421
		it.v.Unreadable = mapBucketContentsNotArrayErr
A
aarzilli 已提交
1422 1423 1424 1425
		return false
	}

	if it.tophashes.Len != it.keys.Len || it.tophashes.Len != it.values.Len {
1426 1427 1428 1429 1430 1431
		it.v.Unreadable = mapBucketContentsInconsistentLenErr
		return false
	}

	if it.overflow.Kind != reflect.Struct {
		it.v.Unreadable = mapBucketsNotStructErr
A
aarzilli 已提交
1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488
		return false
	}

	return true
}

func (it *mapIterator) next() bool {
	for {
		if it.b == nil || it.idx >= it.tophashes.Len {
			r := it.nextBucket()
			if !r {
				return false
			}
			it.idx = 0
		}
		tophash, _ := it.tophashes.sliceAccess(int(it.idx))
		h, err := tophash.asUint()
		if err != nil {
			it.v.Unreadable = fmt.Errorf("unreadable tophash: %v", err)
			return false
		}
		it.idx++
		if h != hashTophashEmpty {
			return true
		}
	}
}

func (it *mapIterator) key() *Variable {
	k, _ := it.keys.sliceAccess(int(it.idx - 1))
	return k
}

func (it *mapIterator) value() *Variable {
	v, _ := it.values.sliceAccess(int(it.idx - 1))
	return v
}

func mapEvacuated(b *Variable) bool {
	if b.Addr == 0 {
		return true
	}
	for _, f := range b.DwarfType.(*dwarf.StructType).Field {
		if f.Name != "tophash" {
			continue
		}
		tophashes, _ := b.toField(f)
		tophash0var, _ := tophashes.sliceAccess(0)
		tophash0, err := tophash0var.asUint()
		if err != nil {
			return true
		}
		return tophash0 > hashTophashEmpty && tophash0 < hashMinTopHash
	}
	return true
}

1489
func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig) {
1490 1491
	var _type, typestring, data *Variable
	var typ dwarf.Type
A
Alessandro Arzilli 已提交
1492
	var err error
1493 1494
	isnil := false

A
Alessandro Arzilli 已提交
1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521
	// An interface variable is implemented either by a runtime.iface
	// struct or a runtime.eface struct. The difference being that empty
	// interfaces (i.e. "interface {}") are represented by runtime.eface
	// and non-empty interfaces by runtime.iface.
	//
	// For both runtime.ifaces and runtime.efaces the data is stored in v.data
	//
	// The concrete type however is stored in v.tab._type for non-empty
	// interfaces and in v._type for empty interfaces.
	//
	// For nil empty interface variables _type will be nil, for nil
	// non-empty interface variables tab will be nil
	//
	// In either case the _type field is a pointer to a runtime._type struct.
	//
	// Before go1.7 _type used to have a field named 'string' containing
	// the name of the type. Since go1.7 the field has been replaced by a
	// str field that contains an offset in the module data, the concrete
	// type must be calculated using the str address along with the value
	// of v.tab._type (v._type for empty interfaces).
	//
	// The following code works for both runtime.iface and runtime.eface
	// and sets the go17 flag when the 'string' field can not be found
	// but the str field was found

	go17 := false

1522 1523
	v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size()))

1524 1525 1526
	ityp := resolveTypedef(&v.RealType.(*dwarf.InterfaceType).TypedefType).(*dwarf.StructType)

	for _, f := range ityp.Field {
1527 1528 1529
		switch f.Name {
		case "tab": // for runtime.iface
			tab, _ := v.toField(f)
A
Alessandro Arzilli 已提交
1530 1531 1532 1533 1534
			tab = tab.maybeDereference()
			isnil = tab.Addr == 0
			if !isnil {
				_type, err = tab.structMember("_type")
				if err != nil {
1535 1536 1537 1538
					v.Unreadable = fmt.Errorf("invalid interface type: %v", err)
					return
				}
				typestring, err = _type.structMember("_string")
A
Alessandro Arzilli 已提交
1539 1540 1541 1542
				if err == nil {
					typestring = typestring.maybeDereference()
				} else {
					go17 = true
1543 1544 1545
				}
			}
		case "_type": // for runtime.eface
A
Alessandro Arzilli 已提交
1546 1547 1548 1549 1550 1551 1552 1553 1554
			_type, _ = v.toField(f)
			_type = _type.maybeDereference()
			isnil = _type.Addr == 0
			if !isnil {
				typestring, err = _type.structMember("_string")
				if err == nil {
					typestring = typestring.maybeDereference()
				} else {
					go17 = true
1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565
				}
			}
		case "data":
			data, _ = v.toField(f)
		}
	}

	if isnil {
		// interface to nil
		data = data.maybeDereference()
		v.Children = []Variable{*data}
A
aarzilli 已提交
1566
		if loadData {
1567
			v.Children[0].loadValueInternal(recurseLevel, cfg)
A
aarzilli 已提交
1568
		}
1569 1570 1571
		return
	}

A
Alessandro Arzilli 已提交
1572
	if data == nil {
1573 1574 1575
		v.Unreadable = fmt.Errorf("invalid interface type")
		return
	}
A
Alessandro Arzilli 已提交
1576

1577 1578
	var kind int64

A
Alessandro Arzilli 已提交
1579 1580 1581
	if go17 {
		// No 'string' field use 'str' and 'runtime.firstmoduledata' to
		// find out what the concrete type is
1582
		_type = _type.maybeDereference()
A
Alessandro Arzilli 已提交
1583

1584 1585
		var typename string
		typename, kind, err = nameOfRuntimeType(_type)
A
Alessandro Arzilli 已提交
1586 1587 1588 1589 1590
		if err != nil {
			v.Unreadable = fmt.Errorf("invalid interface type: %v", err)
			return
		}

1591
		typ, err = v.bi.findType(typename)
A
Alessandro Arzilli 已提交
1592
		if err != nil {
1593
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
1594
			return
A
Alessandro Arzilli 已提交
1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606
		}
	} else {
		if typestring == nil || typestring.Addr == 0 || typestring.Kind != reflect.String {
			v.Unreadable = fmt.Errorf("invalid interface type")
			return
		}
		typestring.loadValue(LoadConfig{false, 0, 512, 0, 0})
		if typestring.Unreadable != nil {
			v.Unreadable = fmt.Errorf("invalid interface type: %v", typestring.Unreadable)
			return
		}

1607
		typename := constant.StringVal(typestring.Value)
1608

1609 1610 1611 1612 1613
		t, err := parser.ParseExpr(typename)
		if err != nil {
			v.Unreadable = fmt.Errorf("invalid interface type, unparsable data type: %v", err)
			return
		}
1614

1615
		typ, err = v.bi.findTypeExpr(t)
1616 1617 1618 1619
		if err != nil {
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
			return
		}
1620 1621
	}

1622 1623 1624
	if kind&kindDirectIface == 0 {
		realtyp := resolveTypedef(typ)
		if _, isptr := realtyp.(*dwarf.PtrType); !isptr {
1625
			typ = pointerTo(typ, v.bi.Arch)
1626
		}
1627 1628
	}

1629
	data = data.newVariable("data", data.Addr, typ)
1630 1631

	v.Children = []Variable{*data}
1632
	if loadData && recurseLevel <= cfg.MaxVariableRecurse {
1633 1634 1635
		v.Children[0].loadValueInternal(recurseLevel, cfg)
	} else {
		v.Children[0].OnlyAddr = true
1636 1637 1638 1639
	}
	return
}

E
epipho 已提交
1640
// Fetches all variables of a specific type in the current function scope
1641
func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg LoadConfig) ([]*Variable, error) {
1642
	reader := scope.DwarfReader()
1643
	off, err := scope.BinInfo.findFunctionDebugInfo(scope.PC)
1644
	if err != nil {
E
epipho 已提交
1645 1646
		return nil, err
	}
A
Alessandro Arzilli 已提交
1647 1648
	reader.Seek(off)
	reader.Next()
E
epipho 已提交
1649

D
Derek Parker 已提交
1650
	var vars []*Variable
1651
	for entry, err := reader.NextScopeVariable(); entry != nil; entry, err = reader.NextScopeVariable() {
E
epipho 已提交
1652 1653 1654
		if err != nil {
			return nil, err
		}
A
Alessandro Arzilli 已提交
1655 1656 1657
		if entry.Tag == 0 {
			break
		}
E
epipho 已提交
1658 1659

		if entry.Tag == tag {
1660
			val, err := scope.extractVariableFromEntry(entry, cfg)
E
epipho 已提交
1661
			if err != nil {
E
epipho 已提交
1662 1663
				// skip variables that we can't parse yet
				continue
E
epipho 已提交
1664 1665 1666 1667 1668
			}

			vars = append(vars, val)
		}
	}
A
Alessandro Arzilli 已提交
1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705
	if len(vars) <= 0 {
		return vars, nil
	}

	// prefetch the whole chunk of memory relative to these variables

	minaddr := vars[0].Addr
	var maxaddr uintptr
	var size int64

	for _, v := range vars {
		if v.Addr < minaddr {
			minaddr = v.Addr
		}

		size += v.DwarfType.Size()

		if end := v.Addr + uintptr(v.DwarfType.Size()); end > maxaddr {
			maxaddr = end
		}
	}

	// check that we aren't trying to cache too much memory: we shouldn't
	// exceed the real size of the variables by more than the number of
	// variables times the size of an architecture pointer (to allow for memory
	// alignment).
	if int64(maxaddr-minaddr)-size <= int64(len(vars))*int64(scope.PtrSize()) {
		mem := cacheMemory(vars[0].mem, minaddr, int(maxaddr-minaddr))

		for _, v := range vars {
			v.mem = mem
		}
	}

	for _, v := range vars {
		v.loadValue(cfg)
	}
E
epipho 已提交
1706 1707 1708

	return vars, nil
}