variables.go 43.3 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
	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)
383 384 385 386
	waitReason := ""
	if wrvar := gvar.fieldVariable("waitreason"); wrvar.Value != nil {
		waitReason = constant.StringVal(wrvar.Value)
	}
387 388 389 390 391 392
	var stackhi uint64
	if stackVar := gvar.fieldVariable("stack"); stackVar != nil {
		if stackhiVar := stackVar.fieldVariable("hi"); stackhiVar != nil {
			stackhi, _ = constant.Uint64Val(stackhiVar.Value)
		}
	}
393

A
Alessandro Arzilli 已提交
394
	stkbarVar, _ := gvar.structMember("stkbar")
395 396 397 398 399 400
	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 已提交
401
	status, _ := constant.Int64Val(gvar.fieldVariable("atomicstatus").Value)
402
	f, l, fn := gvar.bi.PCToLine(uint64(pc))
D
Derek Parker 已提交
403 404 405 406 407 408 409 410
	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 已提交
411
		variable:   gvar,
A
Alessandro Arzilli 已提交
412 413
		stkbarVar:  stkbarVar,
		stkbarPos:  int(stkbarPos),
414
		stackhi:    stackhi,
415
	}
D
Derek Parker 已提交
416 417
	return g, nil
}
418

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

A
Alessandro Arzilli 已提交
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 462 463 464
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)
}

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

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

A
Alessandro Arzilli 已提交
499 500
// Returns the list of saved return addresses used by stack barriers
func (g *G) stkbar() ([]savedLR, error) {
501 502 503
	if g.stkbarVar == nil { // stack barriers were removed in Go 1.9
		return nil, nil
	}
A
Alessandro Arzilli 已提交
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
	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 已提交
524
// EvalVariable returns the value of the given expression (backwards compatibility).
525 526
func (scope *EvalScope) EvalVariable(name string, cfg LoadConfig) (*Variable, error) {
	return scope.EvalExpression(name, cfg)
A
aarzilli 已提交
527
}
528

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

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

A
aarzilli 已提交
541 542 543 544 545 546 547 548 549
	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)
550 551 552
	if err != nil {
		return err
	}
A
aarzilli 已提交
553 554 555 556 557 558

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

559
	yv.loadValue(loadSingleValue)
A
aarzilli 已提交
560 561 562

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

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

	return xv.setValue(yv)
570 571
}

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

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

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

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

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

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

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

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

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

631 632 633 634 635
	for entry, err := reader.NextPackageVariable(); entry != nil; entry, err = reader.NextPackageVariable() {
		if err != nil {
			return nil, err
		}

636 637 638 639
		if typoff, ok := entry.Val(dwarf.AttrType).(dwarf.Offset); !ok || typoff == utypoff {
			continue
		}

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

	return vars, nil
}

652 653
func (scope *EvalScope) packageVarAddr(name string) (*Variable, error) {
	reader := scope.DwarfReader()
654 655 656 657 658 659 660 661 662 663
	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
		}

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

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

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

729 730 731
// 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 已提交
732
	if entry == nil {
D
Derek Parker 已提交
733
		return nil, fmt.Errorf("invalid entry")
E
epipho 已提交
734 735 736 737 738 739 740 741
	}

	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 已提交
742
		return nil, fmt.Errorf("type assertion failed")
E
epipho 已提交
743 744 745 746
	}

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

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

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

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

765
	return scope.newVariable(n, uintptr(addr), t), nil
E
epipho 已提交
766 767
}

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

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

782
		return r
783
	default:
784
		return v
785 786
	}
}
787

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

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

798 799
	v.loaded = true
	switch v.Kind {
A
aarzilli 已提交
800
	case reflect.Ptr, reflect.UnsafePointer:
801 802
		v.Len = 1
		v.Children = []Variable{*v.maybeDereference()}
803 804
		if cfg.FollowPointers {
			// Don't increase the recursion level when dereferencing pointers
805 806 807 808 809 810
			// 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)
811 812 813
		} else {
			v.Children[0].OnlyAddr = true
		}
814

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

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

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

	case reflect.Slice, reflect.Array:
835
		v.loadArrayValues(recurseLevel, cfg)
836 837

	case reflect.Struct:
838
		v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size()))
839 840 841 842
		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.
843
		if recurseLevel <= cfg.MaxVariableRecurse {
844 845
			v.Children = make([]Variable, 0, len(t.Field))
			for i, field := range t.Field {
846 847 848
				if cfg.MaxStructFields >= 0 && len(v.Children) >= cfg.MaxStructFields {
					break
				}
849 850 851
				f, _ := v.toField(field)
				v.Children = append(v.Children, *f)
				v.Children[i].Name = field.Name
852
				v.Children[i].loadValueInternal(recurseLevel+1, cfg)
853
			}
854 855
		}

856
	case reflect.Interface:
857
		v.loadInterface(recurseLevel, true, cfg)
858

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

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

A
aarzilli 已提交
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
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())
914
	default:
915 916
		if t, isptr := v.RealType.(*dwarf.PtrType); isptr {
			err = v.writeUint(uint64(y.Children[0].Addr), int64(t.ByteSize))
A
aarzilli 已提交
917 918 919
		} else {
			return fmt.Errorf("can not set variables of type %s (not implemented)", v.Kind.String())
		}
920
	}
A
aarzilli 已提交
921 922

	return err
923 924
}

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

929 930
	mem = cacheMemory(mem, addr, arch.PtrSize()*2)

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

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

A
aarzilli 已提交
952 953 954
	return addr, strlen, nil
}

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

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

967 968
	retstr := *(*string)(unsafe.Pointer(&val))

A
aarzilli 已提交
969 970 971
	return retstr, nil
}

972
func (v *Variable) loadSliceInfo(t *dwarf.SliceType) {
973 974
	v.mem = cacheMemory(v.mem, v.Addr, int(t.Size()))

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

1012
	v.stride = v.fieldType.Size()
1013 1014
	if t, ok := v.fieldType.(*dwarf.PtrType); ok {
		v.stride = t.ByteSize
1015
	}
1016

1017
	return
1018 1019
}

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

1029 1030
	count := v.Len
	// Cap number of elements
1031 1032
	if count > int64(cfg.MaxArrayValues) {
		count = int64(cfg.MaxArrayValues)
1033
	}
1034

1035
	if v.stride < maxArrayStridePrefetch {
1036
		v.mem = cacheMemory(v.mem, v.Base, int(v.stride*count))
1037
	}
1038

1039 1040 1041
	errcount := 0

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

		if fieldvar.Unreadable != nil {
1046
			errcount++
E
epipho 已提交
1047
		}
1048

1049
		v.Children = append(v.Children, *fieldvar)
1050 1051 1052
		if errcount > maxErrCount {
			break
		}
1053 1054 1055
	}
}

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

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

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

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

1087
func readIntRaw(mem MemoryReadWriter, addr uintptr, size int64) (int64, error) {
E
epipho 已提交
1088
	var n int64
1089

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

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

D
Derek Parker 已提交
1107
	return n, nil
E
epipho 已提交
1108 1109
}

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

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

1124
	_, err := v.mem.WriteMemory(v.Addr, val)
1125 1126 1127
	return err
}

1128
func readUintRaw(mem MemoryReadWriter, addr uintptr, size int64) (uint64, error) {
E
epipho 已提交
1129 1130
	var n uint64

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

	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 已提交
1148
	return n, nil
1149 1150
}

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

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

1170
	return 0.0, fmt.Errorf("could not read float")
1171 1172
}

1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184
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)
	}

1185
	_, err := v.mem.WriteMemory(v.Addr, buf.Bytes())
1186 1187 1188
	return err
}

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

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

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

1212
	_, err = v.mem.ReadMemory(val, fnaddr)
1213
	if err != nil {
1214 1215
		v.Unreadable = err
		return
1216 1217
	}

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

1225
	v.Value = constant.MakeString(fn.Name)
1226 1227
}

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

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

	count := 0
	errcount := 0
	for it.next() {
1244
		if count >= cfg.MaxArrayValues {
A
aarzilli 已提交
1245 1246 1247
			break
		}
		key := it.key()
1248 1249 1250 1251 1252 1253
		var val *Variable
		if it.values.fieldType.Size() > 0 {
			val = it.value()
		} else {
			val = v.newVariable("", it.values.Addr, it.values.fieldType)
		}
1254 1255
		key.loadValueInternal(recurseLevel+1, cfg)
		val.loadValueInternal(recurseLevel+1, cfg)
A
aarzilli 已提交
1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286
		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 {
1287 1288 1289
	sv := v.clone()
	sv.RealType = resolveTypedef(&(sv.RealType.(*dwarf.MapType).TypedefType))
	sv = sv.maybeDereference()
1290
	v.Base = sv.Addr
A
aarzilli 已提交
1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304

	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
	}

1305
	v.mem = cacheMemory(v.mem, v.Base, int(v.RealType.Size()))
1306

A
aarzilli 已提交
1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328
	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
		}
	}

1329 1330 1331 1332 1333
	if it.buckets.Kind != reflect.Struct || it.oldbuckets.Kind != reflect.Struct {
		v.Unreadable = mapBucketsNotStructErr
		return nil
	}

A
aarzilli 已提交
1334 1335 1336
	return it
}

1337 1338 1339 1340
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 已提交
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 1384 1385 1386 1387 1388 1389 1390 1391
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
	}

1392 1393
	it.b.mem = cacheMemory(it.b.mem, it.b.Addr, int(it.b.RealType.Size()))

A
aarzilli 已提交
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 1421 1422 1423 1424 1425 1426 1427 1428
	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 {
1429
		it.v.Unreadable = mapBucketContentsNotArrayErr
A
aarzilli 已提交
1430 1431 1432
		return false
	}

1433 1434 1435 1436 1437 1438 1439 1440
	if it.tophashes.Len != it.keys.Len {
		it.v.Unreadable = mapBucketContentsInconsistentLenErr
		return false
	}

	if it.values.fieldType.Size() > 0 && it.tophashes.Len != it.values.Len {
		// if the type of the value is zero-sized (i.e. struct{}) then the values
		// array's length is zero.
1441 1442 1443 1444 1445 1446
		it.v.Unreadable = mapBucketContentsInconsistentLenErr
		return false
	}

	if it.overflow.Kind != reflect.Struct {
		it.v.Unreadable = mapBucketsNotStructErr
A
aarzilli 已提交
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 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503
		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
}

1504
func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig) {
1505 1506
	var _type, typestring, data *Variable
	var typ dwarf.Type
A
Alessandro Arzilli 已提交
1507
	var err error
1508 1509
	isnil := false

A
Alessandro Arzilli 已提交
1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536
	// 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

1537 1538
	v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size()))

1539 1540 1541
	ityp := resolveTypedef(&v.RealType.(*dwarf.InterfaceType).TypedefType).(*dwarf.StructType)

	for _, f := range ityp.Field {
1542 1543 1544
		switch f.Name {
		case "tab": // for runtime.iface
			tab, _ := v.toField(f)
A
Alessandro Arzilli 已提交
1545 1546 1547 1548 1549
			tab = tab.maybeDereference()
			isnil = tab.Addr == 0
			if !isnil {
				_type, err = tab.structMember("_type")
				if err != nil {
1550 1551 1552 1553
					v.Unreadable = fmt.Errorf("invalid interface type: %v", err)
					return
				}
				typestring, err = _type.structMember("_string")
A
Alessandro Arzilli 已提交
1554 1555 1556 1557
				if err == nil {
					typestring = typestring.maybeDereference()
				} else {
					go17 = true
1558 1559 1560
				}
			}
		case "_type": // for runtime.eface
A
Alessandro Arzilli 已提交
1561 1562 1563 1564 1565 1566 1567 1568 1569
			_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
1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580
				}
			}
		case "data":
			data, _ = v.toField(f)
		}
	}

	if isnil {
		// interface to nil
		data = data.maybeDereference()
		v.Children = []Variable{*data}
A
aarzilli 已提交
1581
		if loadData {
1582
			v.Children[0].loadValueInternal(recurseLevel, cfg)
A
aarzilli 已提交
1583
		}
1584 1585 1586
		return
	}

A
Alessandro Arzilli 已提交
1587
	if data == nil {
1588 1589 1590
		v.Unreadable = fmt.Errorf("invalid interface type")
		return
	}
A
Alessandro Arzilli 已提交
1591

1592 1593
	var kind int64

A
Alessandro Arzilli 已提交
1594 1595 1596
	if go17 {
		// No 'string' field use 'str' and 'runtime.firstmoduledata' to
		// find out what the concrete type is
1597
		_type = _type.maybeDereference()
A
Alessandro Arzilli 已提交
1598

1599 1600
		var typename string
		typename, kind, err = nameOfRuntimeType(_type)
A
Alessandro Arzilli 已提交
1601 1602 1603 1604 1605
		if err != nil {
			v.Unreadable = fmt.Errorf("invalid interface type: %v", err)
			return
		}

1606
		typ, err = v.bi.findType(typename)
A
Alessandro Arzilli 已提交
1607
		if err != nil {
1608
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
1609
			return
A
Alessandro Arzilli 已提交
1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621
		}
	} 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
		}

1622
		typename := constant.StringVal(typestring.Value)
1623

1624 1625 1626 1627 1628
		t, err := parser.ParseExpr(typename)
		if err != nil {
			v.Unreadable = fmt.Errorf("invalid interface type, unparsable data type: %v", err)
			return
		}
1629

1630
		typ, err = v.bi.findTypeExpr(t)
1631 1632 1633 1634
		if err != nil {
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
			return
		}
1635 1636
	}

1637 1638 1639
	if kind&kindDirectIface == 0 {
		realtyp := resolveTypedef(typ)
		if _, isptr := realtyp.(*dwarf.PtrType); !isptr {
1640
			typ = pointerTo(typ, v.bi.Arch)
1641
		}
1642 1643
	}

1644
	data = data.newVariable("data", data.Addr, typ)
1645 1646

	v.Children = []Variable{*data}
1647
	if loadData && recurseLevel <= cfg.MaxVariableRecurse {
1648 1649 1650
		v.Children[0].loadValueInternal(recurseLevel, cfg)
	} else {
		v.Children[0].OnlyAddr = true
1651 1652 1653 1654
	}
	return
}

E
epipho 已提交
1655
// Fetches all variables of a specific type in the current function scope
1656
func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg LoadConfig) ([]*Variable, error) {
1657
	reader := scope.DwarfReader()
1658
	off, err := scope.BinInfo.findFunctionDebugInfo(scope.PC)
1659
	if err != nil {
E
epipho 已提交
1660 1661
		return nil, err
	}
A
Alessandro Arzilli 已提交
1662 1663
	reader.Seek(off)
	reader.Next()
E
epipho 已提交
1664

D
Derek Parker 已提交
1665
	var vars []*Variable
1666
	for entry, err := reader.NextScopeVariable(); entry != nil; entry, err = reader.NextScopeVariable() {
E
epipho 已提交
1667 1668 1669
		if err != nil {
			return nil, err
		}
A
Alessandro Arzilli 已提交
1670 1671 1672
		if entry.Tag == 0 {
			break
		}
E
epipho 已提交
1673 1674

		if entry.Tag == tag {
1675
			val, err := scope.extractVariableFromEntry(entry, cfg)
E
epipho 已提交
1676
			if err != nil {
E
epipho 已提交
1677 1678
				// skip variables that we can't parse yet
				continue
E
epipho 已提交
1679 1680 1681 1682 1683
			}

			vars = append(vars, val)
		}
	}
A
Alessandro Arzilli 已提交
1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720
	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 已提交
1721 1722 1723

	return vars, nil
}