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

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

17
	"github.com/derekparker/delve/pkg/dwarf/godwarf"
D
Derek Parker 已提交
18 19
	"github.com/derekparker/delve/pkg/dwarf/op"
	"github.com/derekparker/delve/pkg/dwarf/reader"
20 21
)

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

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

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

	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
32 33
)

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

const (
	FloatIsNormal FloatSpecial = iota
	FloatIsNaN
	FloatIsPosInf
	FloatIsNegInf
)

43 44 45 46 47 48 49
type VariableFlags uint16

const (
	// VariableEscaped is set for local variables that escaped to the heap
	VariableEscaped VariableFlags = (1 << iota)
)

D
Derek Parker 已提交
50 51 52 53
// 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.
54
type Variable struct {
55
	Addr      uintptr
A
aarzilli 已提交
56
	OnlyAddr  bool
57
	Name      string
58 59
	DwarfType godwarf.Type
	RealType  godwarf.Type
60
	Kind      reflect.Kind
61
	mem       MemoryReadWriter
62
	bi        *BinaryInfo
63

64 65
	Value        constant.Value
	FloatSpecial FloatSpecial
66 67 68 69

	Len int64
	Cap int64

70 71
	Flags VariableFlags

72 73
	// 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 已提交
74
	// address of the struct backing chan and map variables
A
aarzilli 已提交
75
	// address of the function entry point for function variables (0 for nil function pointers)
76
	Base      uintptr
77
	stride    int64
78
	fieldType godwarf.Type
79

A
aarzilli 已提交
80 81 82
	// number of elements to skip when loading a map
	mapSkip int

83 84 85 86
	Children []Variable

	loaded     bool
	Unreadable error
87 88
}

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
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 已提交
105
// G status, from: src/runtime/runtime2.go
106
const (
D
Derek Parker 已提交
107 108 109 110 111 112 113 114 115
	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
116 117
)

D
Derek Parker 已提交
118
// G represents a runtime G (goroutine) structure (at least the
119
// fields that Delve is interested in).
D
Derek Parker 已提交
120
type G struct {
D
Derek Parker 已提交
121
	ID         int    // Goroutine ID
122 123 124 125
	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.
126
	Status     uint64
A
Alessandro Arzilli 已提交
127 128
	stkbarVar  *Variable // stkbar field of g struct
	stkbarPos  int       // stkbarPos field of g struct
129
	stackhi    uint64    // value of stack.hi
130

131
	// Information on goroutine location
132
	CurrentLoc Location
133

A
aarzilli 已提交
134
	// Thread that this goroutine is currently allocated to
135
	Thread Thread
136

A
Alessandro Arzilli 已提交
137
	variable *Variable
138 139
}

D
Derek Parker 已提交
140 141
// EvalScope is the scope for variable evaluation. Contains the thread,
// current location (PC), and canonical frame address.
142
type EvalScope struct {
143 144 145 146 147
	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
148
	StackHi uint64
149 150
}

D
Derek Parker 已提交
151
// IsNilErr is returned when a variable is nil.
152 153 154 155 156 157 158 159
type IsNilErr struct {
	name string
}

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

160
func (scope *EvalScope) newVariable(name string, addr uintptr, dwarfType godwarf.Type) *Variable {
161
	return newVariable(name, addr, dwarfType, scope.BinInfo, scope.Mem)
162 163
}

164
func newVariableFromThread(t Thread, name string, addr uintptr, dwarfType godwarf.Type) *Variable {
165
	return newVariable(name, addr, dwarfType, t.BinInfo(), t)
166 167
}

168
func (v *Variable) newVariable(name string, addr uintptr, dwarfType godwarf.Type) *Variable {
169
	return newVariable(name, addr, dwarfType, v.bi, v.mem)
170 171
}

172
func newVariable(name string, addr uintptr, dwarfType godwarf.Type, bi *BinaryInfo, mem MemoryReadWriter) *Variable {
173 174 175
	v := &Variable{
		Name:      name,
		Addr:      addr,
176
		DwarfType: dwarfType,
177
		mem:       mem,
178
		bi:        bi,
179 180
	}

181
	v.RealType = resolveTypedef(v.DwarfType)
182 183

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

		if t.Count > 0 {
			v.stride = t.ByteSize / t.Count
		}
220
	case *godwarf.ComplexType:
221 222 223 224 225 226
		switch t.ByteSize {
		case 8:
			v.Kind = reflect.Complex64
		case 16:
			v.Kind = reflect.Complex128
		}
227
	case *godwarf.IntType:
228
		v.Kind = reflect.Int
229
	case *godwarf.UintType:
230
		v.Kind = reflect.Uint
231
	case *godwarf.FloatType:
232 233 234 235 236 237
		switch t.ByteSize {
		case 4:
			v.Kind = reflect.Float32
		case 8:
			v.Kind = reflect.Float64
		}
238
	case *godwarf.BoolType:
239
		v.Kind = reflect.Bool
240
	case *godwarf.FuncType:
241
		v.Kind = reflect.Func
242
	case *godwarf.VoidType:
243
		v.Kind = reflect.Invalid
244
	case *godwarf.UnspecifiedType:
245 246 247
		v.Kind = reflect.Invalid
	default:
		v.Unreadable = fmt.Errorf("Unknown type: %T", t)
248 249
	}

250 251 252
	return v
}

253
func resolveTypedef(typ godwarf.Type) godwarf.Type {
254
	for {
255
		if tt, ok := typ.(*godwarf.TypedefType); ok {
256 257 258 259 260 261 262
			typ = tt.Type
		} else {
			return typ
		}
	}
}

263
func newConstant(val constant.Value, mem MemoryReadWriter) *Variable {
264
	v := &Variable{Value: val, mem: mem, loaded: true}
A
aarzilli 已提交
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
	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{
282
	Name:     "nil",
A
aarzilli 已提交
283
	Addr:     0,
284
	Base:     0,
A
aarzilli 已提交
285 286 287 288
	Kind:     reflect.Ptr,
	Children: []Variable{{Addr: 0, OnlyAddr: true}},
}

289 290 291
func (v *Variable) clone() *Variable {
	r := *v
	return &r
292 293
}

D
Derek Parker 已提交
294 295
// TypeString returns the string representation
// of the type of this variable.
296 297 298 299 300
func (v *Variable) TypeString() string {
	if v == nilVariable {
		return "nil"
	}
	if v.DwarfType != nil {
301
		return v.DwarfType.Common().Name
302 303 304 305
	}
	return v.Kind.String()
}

306
func (v *Variable) toField(field *godwarf.StructField) (*Variable, error) {
307 308 309
	if v.Unreadable != nil {
		return v.clone(), nil
	}
D
Derek Parker 已提交
310
	if v.Addr == 0 {
311
		return nil, &IsNilErr{v.Name}
D
Derek Parker 已提交
312 313
	}

314 315
	name := ""
	if v.Name != "" {
316 317 318 319
		parts := strings.Split(field.Name, ".")
		if len(parts) > 1 {
			name = fmt.Sprintf("%s.%s", v.Name, parts[1])
		} else {
D
Derek Parker 已提交
320
			name = fmt.Sprintf("%s.%s", v.Name, field.Name)
321
		}
322
	}
323
	return v.newVariable(name, uintptr(int64(v.Addr)+field.ByteOffset), field.Type), nil
324 325
}

D
Derek Parker 已提交
326 327
// DwarfReader returns the DwarfReader containing the
// Dwarf information for the target process.
328
func (scope *EvalScope) DwarfReader() *reader.Reader {
329
	return scope.BinInfo.DwarfReader()
330 331
}

D
Derek Parker 已提交
332
// Type returns the Dwarf type entry at `offset`.
333 334
func (scope *EvalScope) Type(offset dwarf.Offset) (godwarf.Type, error) {
	return godwarf.ReadType(scope.BinInfo.dwarf, offset, scope.BinInfo.typeCache)
335 336
}

D
Derek Parker 已提交
337
// PtrSize returns the size of a pointer.
338
func (scope *EvalScope) PtrSize() int {
339
	return scope.BinInfo.Arch.PtrSize()
340 341
}

A
aarzilli 已提交
342
// ChanRecvBlocked returns whether the goroutine is blocked on
343
// a channel read operation.
344
func (g *G) ChanRecvBlocked() bool {
345
	return (g.Thread == nil) && (g.WaitReason == chanRecv)
D
Derek Parker 已提交
346 347
}

D
Derek Parker 已提交
348 349
// NoGError returned when a G could not be found
// for a specific thread.
350 351 352 353 354 355 356 357
type NoGError struct {
	tid int
}

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

358 359 360
func (gvar *Variable) parseG() (*G, error) {
	mem := gvar.mem
	gaddr := uint64(gvar.Addr)
361
	_, deref := gvar.RealType.(*godwarf.PtrType)
362

363
	if deref {
364
		gaddrbytes := make([]byte, gvar.bi.Arch.PtrSize())
365
		_, err := mem.ReadMemory(gaddrbytes, uintptr(gaddr))
366 367 368 369
		if err != nil {
			return nil, fmt.Errorf("error derefing *G %s", err)
		}
		gaddr = binary.LittleEndian.Uint64(gaddrbytes)
370
	}
D
Derek Parker 已提交
371
	if gaddr == 0 {
372
		id := 0
373
		if thread, ok := mem.(Thread); ok {
374
			id = thread.ThreadID()
375
		}
A
Alessandro Arzilli 已提交
376
		return nil, NoGError{tid: id}
377
	}
A
Alessandro Arzilli 已提交
378
	for {
379
		if _, isptr := gvar.RealType.(*godwarf.PtrType); !isptr {
A
Alessandro Arzilli 已提交
380 381 382 383
			break
		}
		gvar = gvar.maybeDereference()
	}
384
	gvar.loadValue(LoadConfig{false, 2, 64, 0, -1})
D
Derek Parker 已提交
385 386
	if gvar.Unreadable != nil {
		return nil, gvar.Unreadable
387
	}
A
Alessandro Arzilli 已提交
388 389 390 391 392
	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)
393 394 395 396
	waitReason := ""
	if wrvar := gvar.fieldVariable("waitreason"); wrvar.Value != nil {
		waitReason = constant.StringVal(wrvar.Value)
	}
397 398 399 400 401 402
	var stackhi uint64
	if stackVar := gvar.fieldVariable("stack"); stackVar != nil {
		if stackhiVar := stackVar.fieldVariable("hi"); stackhiVar != nil {
			stackhi, _ = constant.Uint64Val(stackhiVar.Value)
		}
	}
403

A
Alessandro Arzilli 已提交
404
	stkbarVar, _ := gvar.structMember("stkbar")
405 406 407 408 409 410
	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 已提交
411
	status, _ := constant.Int64Val(gvar.fieldVariable("atomicstatus").Value)
412
	f, l, fn := gvar.bi.PCToLine(uint64(pc))
D
Derek Parker 已提交
413 414 415 416 417 418 419 420
	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 已提交
421
		variable:   gvar,
A
Alessandro Arzilli 已提交
422 423
		stkbarVar:  stkbarVar,
		stkbarPos:  int(stkbarPos),
424
		stackhi:    stackhi,
425
	}
D
Derek Parker 已提交
426 427
	return g, nil
}
428

A
Alessandro Arzilli 已提交
429
func (v *Variable) loadFieldNamed(name string) *Variable {
D
Derek Parker 已提交
430
	v, err := v.structMember(name)
431
	if err != nil {
D
Derek Parker 已提交
432
		return nil
433
	}
434
	v.loadValue(loadFullValue)
D
Derek Parker 已提交
435 436
	if v.Unreadable != nil {
		return nil
437
	}
D
Derek Parker 已提交
438
	return v
439 440
}

A
Alessandro Arzilli 已提交
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
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)
}

475 476 477 478 479 480 481 482
// 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 已提交
483 484
// UserCurrent returns the location the users code is at,
// or was at before entering a runtime function.
485
func (g *G) UserCurrent() Location {
A
aarzilli 已提交
486 487 488
	it, err := g.stackIterator()
	if err != nil {
		return g.CurrentLoc
489 490 491
	}
	for it.Next() {
		frame := it.Frame()
492 493
		if frame.Call.Fn != nil {
			name := frame.Call.Fn.Name
494
			if strings.Contains(name, ".") && (!strings.HasPrefix(name, "runtime.") || isExportedRuntime(name)) {
495 496
				return frame.Call
			}
497 498
		}
	}
499
	return g.CurrentLoc
500 501
}

D
Derek Parker 已提交
502 503
// Go returns the location of the 'go' statement
// that spawned this goroutine.
504
func (g *G) Go() Location {
505
	f, l, fn := g.variable.bi.goSymTable.PCToLine(g.GoPC)
506 507 508
	return Location{PC: g.GoPC, File: f, Line: l, Fn: fn}
}

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

D
Derek Parker 已提交
539
// SetVariable sets the value of the named variable
A
aarzilli 已提交
540 541
func (scope *EvalScope) SetVariable(name, value string) error {
	t, err := parser.ParseExpr(name)
542
	if err != nil {
A
aarzilli 已提交
543
		return err
544 545
	}

A
aarzilli 已提交
546
	xv, err := scope.evalAST(t)
547
	if err != nil {
A
aarzilli 已提交
548
		return err
549
	}
550

A
aarzilli 已提交
551 552 553 554 555 556 557 558 559
	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)
560 561 562
	if err != nil {
		return err
	}
A
aarzilli 已提交
563 564 565 566 567 568

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

569
	yv.loadValue(loadSingleValue)
A
aarzilli 已提交
570 571 572

	if err := yv.isType(xv.RealType, xv.Kind); err != nil {
		return err
573
	}
A
aarzilli 已提交
574 575 576 577 578 579

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

	return xv.setValue(yv)
580 581
}

582
func (scope *EvalScope) extractVariableFromEntry(entry *dwarf.Entry, cfg LoadConfig) (*Variable, error) {
583
	rdr := scope.DwarfReader()
584
	v, err := scope.extractVarInfoFromEntry(entry, rdr)
585
	if err != nil {
D
Derek Parker 已提交
586 587
		return nil, err
	}
588
	return v, nil
589
}
D
Derek Parker 已提交
590

591 592
func (scope *EvalScope) extractVarInfo(varName string) (*Variable, error) {
	reader := scope.DwarfReader()
593
	off, err := scope.BinInfo.findFunctionDebugInfo(scope.PC)
594 595
	if err != nil {
		return nil, err
596
	}
A
Alessandro Arzilli 已提交
597 598
	reader.Seek(off)
	reader.Next()
599

600
	for entry, err := reader.NextScopeVariable(); entry != nil; entry, err = reader.NextScopeVariable() {
D
Derek Parker 已提交
601
		if err != nil {
602
			return nil, err
D
Derek Parker 已提交
603
		}
A
Alessandro Arzilli 已提交
604 605 606
		if entry.Tag == 0 {
			break
		}
D
Derek Parker 已提交
607 608 609 610 611 612

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

613
		if n == varName {
614
			return scope.extractVarInfoFromEntry(entry, reader)
D
Derek Parker 已提交
615 616
		}
	}
617
	return nil, fmt.Errorf("could not find symbol value for %s", varName)
D
Derek Parker 已提交
618
}
619

620
// LocalVariables returns all local variables from the current function scope.
621 622
func (scope *EvalScope) LocalVariables(cfg LoadConfig) ([]*Variable, error) {
	return scope.variablesByTag(dwarf.TagVariable, cfg)
623 624 625
}

// FunctionArguments returns the name, value, and type of all current function arguments.
626 627
func (scope *EvalScope) FunctionArguments(cfg LoadConfig) ([]*Variable, error) {
	return scope.variablesByTag(dwarf.TagFormalParameter, cfg)
628 629 630
}

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

635 636 637 638 639 640
	var utypoff dwarf.Offset
	utypentry, err := reader.SeekToTypeNamed("<unspecified>")
	if err == nil {
		utypoff = utypentry.Offset
	}

641 642 643 644 645
	for entry, err := reader.NextPackageVariable(); entry != nil; entry, err = reader.NextPackageVariable() {
		if err != nil {
			return nil, err
		}

646 647 648 649
		if typoff, ok := entry.Val(dwarf.AttrType).(dwarf.Offset); !ok || typoff == utypoff {
			continue
		}

650
		// Ignore errors trying to extract values
651
		val, err := scope.extractVariableFromEntry(entry, cfg)
652 653 654
		if err != nil {
			continue
		}
A
Alessandro Arzilli 已提交
655
		val.loadValue(cfg)
656 657 658 659 660 661
		vars = append(vars, val)
	}

	return vars, nil
}

662
func (scope *EvalScope) packageVarAddr(name string) (*Variable, error) {
663
	for n, off := range scope.BinInfo.packageVars {
664
		if n == name || strings.HasSuffix(n, "/"+name) {
665 666 667 668 669 670
			reader := scope.DwarfReader()
			reader.Seek(off)
			entry, err := reader.Next()
			if err != nil {
				return nil, err
			}
671
			return scope.extractVarInfoFromEntry(entry, reader)
672 673 674 675 676
		}
	}
	return nil, fmt.Errorf("could not find symbol value for %s", name)
}

677
func (v *Variable) structMember(memberName string) (*Variable, error) {
678 679 680 681
	if v.Unreadable != nil {
		return v.clone(), nil
	}
	structVar := v.maybeDereference()
682
	structVar.Name = v.Name
683 684
	if structVar.Unreadable != nil {
		return structVar, nil
685
	}
686 687

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

736 737 738
// 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 已提交
739
	if entry == nil {
D
Derek Parker 已提交
740
		return nil, fmt.Errorf("invalid entry")
E
epipho 已提交
741 742 743 744 745 746 747 748
	}

	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 已提交
749
		return nil, fmt.Errorf("type assertion failed")
E
epipho 已提交
750 751 752 753
	}

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

757
	t, err := scope.Type(offset)
E
epipho 已提交
758 759 760 761 762 763
	if err != nil {
		return nil, err
	}

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

767
	addr, err := op.ExecuteStackProgram(scope.CFA, instructions)
E
epipho 已提交
768 769 770 771
	if err != nil {
		return nil, err
	}

772
	return scope.newVariable(n, uintptr(addr), t), nil
E
epipho 已提交
773 774
}

775
// If v is a pointer a new variable is returned containing the value pointed by v.
776 777 778 779
func (v *Variable) maybeDereference() *Variable {
	if v.Unreadable != nil {
		return v
	}
780

781
	switch t := v.RealType.(type) {
782
	case *godwarf.PtrType:
783 784
		ptrval, err := readUintRaw(v.mem, uintptr(v.Addr), t.ByteSize)
		r := v.newVariable("", uintptr(ptrval), t.Type)
785
		if err != nil {
786
			r.Unreadable = err
787 788
		}

789
		return r
790
	default:
791
		return v
792 793
	}
}
794

795
// Extracts the value of the variable at the given address.
796 797
func (v *Variable) loadValue(cfg LoadConfig) {
	v.loadValueInternal(0, cfg)
798 799
}

800
func (v *Variable) loadValueInternal(recurseLevel int, cfg LoadConfig) {
801
	if v.Unreadable != nil || v.loaded || (v.Addr == 0 && v.Base == 0) {
802 803
		return
	}
804

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

A
aarzilli 已提交
822
	case reflect.Chan:
823
		sv := v.clone()
824
		sv.RealType = resolveTypedef(&(sv.RealType.(*godwarf.ChanType).TypedefType))
825
		sv = sv.maybeDereference()
826
		sv.loadValueInternal(0, loadFullValue)
A
aarzilli 已提交
827 828
		v.Children = sv.Children
		v.Len = sv.Len
829
		v.Base = sv.Addr
A
aarzilli 已提交
830

A
aarzilli 已提交
831
	case reflect.Map:
832 833
		if recurseLevel <= cfg.MaxVariableRecurse {
			v.loadMap(recurseLevel, cfg)
834 835 836
		} else {
			// loads length so that the client knows that the map isn't empty
			v.mapIterator()
A
aarzilli 已提交
837
		}
A
aarzilli 已提交
838

839
	case reflect.String:
840
		var val string
841
		val, v.Unreadable = readStringValue(v.mem, v.Base, v.Len, cfg)
842
		v.Value = constant.MakeString(val)
843 844

	case reflect.Slice, reflect.Array:
845
		v.loadArrayValues(recurseLevel, cfg)
846 847

	case reflect.Struct:
848
		v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size()))
849
		t := v.RealType.(*godwarf.StructType)
850 851 852
		v.Len = int64(len(t.Field))
		// Recursively call extractValue to grab
		// the value of all the members of the struct.
853
		if recurseLevel <= cfg.MaxVariableRecurse {
854 855
			v.Children = make([]Variable, 0, len(t.Field))
			for i, field := range t.Field {
856 857 858
				if cfg.MaxStructFields >= 0 && len(v.Children) >= cfg.MaxStructFields {
					break
				}
859 860 861
				f, _ := v.toField(field)
				v.Children = append(v.Children, *f)
				v.Children[i].Name = field.Name
862
				v.Children[i].loadValueInternal(recurseLevel+1, cfg)
863
			}
864 865
		}

866
	case reflect.Interface:
867
		v.loadInterface(recurseLevel, true, cfg)
868

869
	case reflect.Complex64, reflect.Complex128:
870
		v.readComplex(v.RealType.(*godwarf.ComplexType).ByteSize)
871
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
872
		var val int64
873
		val, v.Unreadable = readIntRaw(v.mem, v.Addr, v.RealType.(*godwarf.IntType).ByteSize)
874
		v.Value = constant.MakeInt64(val)
875
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
876
		var val uint64
877
		val, v.Unreadable = readUintRaw(v.mem, v.Addr, v.RealType.(*godwarf.UintType).ByteSize)
878 879
		v.Value = constant.MakeUint64(val)

880
	case reflect.Bool:
881 882
		val := make([]byte, 1)
		_, err := v.mem.ReadMemory(val, v.Addr)
883 884
		v.Unreadable = err
		if err == nil {
885
			v.Value = constant.MakeBool(val[0] != 0)
886
		}
887
	case reflect.Float32, reflect.Float64:
888
		var val float64
889
		val, v.Unreadable = v.readFloatRaw(v.RealType.(*godwarf.FloatType).ByteSize)
890
		v.Value = constant.MakeFloat64(val)
891 892 893 894 895 896 897 898
		switch {
		case math.IsInf(val, +1):
			v.FloatSpecial = FloatIsPosInf
		case math.IsInf(val, -1):
			v.FloatSpecial = FloatIsNegInf
		case math.IsNaN(val):
			v.FloatSpecial = FloatIsNaN
		}
899 900
	case reflect.Func:
		v.readFunctionPtr()
901
	default:
902
		v.Unreadable = fmt.Errorf("unknown or unsupported kind: \"%s\"", v.Kind.String())
903 904 905
	}
}

A
aarzilli 已提交
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923
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())
924
	default:
925
		if t, isptr := v.RealType.(*godwarf.PtrType); isptr {
926
			err = v.writeUint(uint64(y.Children[0].Addr), int64(t.ByteSize))
A
aarzilli 已提交
927 928 929
		} else {
			return fmt.Errorf("can not set variables of type %s (not implemented)", v.Kind.String())
		}
930
	}
A
aarzilli 已提交
931 932

	return err
933 934
}

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

939 940
	mem = cacheMemory(mem, addr, arch.PtrSize()*2)

941
	// read len
942 943
	val := make([]byte, arch.PtrSize())
	_, err := mem.ReadMemory(val, addr+uintptr(arch.PtrSize()))
944
	if err != nil {
A
aarzilli 已提交
945
		return 0, 0, fmt.Errorf("could not read string len %s", err)
946
	}
947
	strlen := int64(binary.LittleEndian.Uint64(val))
948
	if strlen < 0 {
A
aarzilli 已提交
949
		return 0, 0, fmt.Errorf("invalid length: %d", strlen)
950
	}
951 952

	// read addr
953
	_, err = mem.ReadMemory(val, addr)
954
	if err != nil {
A
aarzilli 已提交
955
		return 0, 0, fmt.Errorf("could not read string pointer %s", err)
956 957
	}
	addr = uintptr(binary.LittleEndian.Uint64(val))
D
Derek Parker 已提交
958
	if addr == 0 {
A
aarzilli 已提交
959
		return 0, 0, nil
D
Derek Parker 已提交
960
	}
D
Derek Parker 已提交
961

A
aarzilli 已提交
962 963 964
	return addr, strlen, nil
}

965
func readStringValue(mem MemoryReadWriter, addr uintptr, strlen int64, cfg LoadConfig) (string, error) {
A
aarzilli 已提交
966
	count := strlen
967 968
	if count > int64(cfg.MaxStringLen) {
		count = int64(cfg.MaxStringLen)
A
aarzilli 已提交
969 970
	}

971 972
	val := make([]byte, int(count))
	_, err := mem.ReadMemory(val, addr)
973
	if err != nil {
A
aarzilli 已提交
974
		return "", fmt.Errorf("could not read string at %#v due to %s", addr, err)
975 976
	}

977 978
	retstr := *(*string)(unsafe.Pointer(&val))

A
aarzilli 已提交
979 980 981
	return retstr, nil
}

982
func (v *Variable) loadSliceInfo(t *godwarf.SliceType) {
983 984
	v.mem = cacheMemory(v.mem, v.Addr, int(t.Size()))

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

1022
	v.stride = v.fieldType.Size()
1023
	if t, ok := v.fieldType.(*godwarf.PtrType); ok {
1024
		v.stride = t.ByteSize
1025 1026 1027
	}
}

1028
func (v *Variable) loadArrayValues(recurseLevel int, cfg LoadConfig) {
1029 1030 1031
	if v.Unreadable != nil {
		return
	}
1032 1033 1034 1035
	if v.Len < 0 {
		v.Unreadable = errors.New("Negative array length")
		return
	}
1036

1037 1038
	count := v.Len
	// Cap number of elements
1039 1040
	if count > int64(cfg.MaxArrayValues) {
		count = int64(cfg.MaxArrayValues)
1041
	}
1042

1043
	if v.stride < maxArrayStridePrefetch {
1044
		v.mem = cacheMemory(v.mem, v.Base, int(v.stride*count))
1045
	}
1046

1047 1048 1049
	errcount := 0

	for i := int64(0); i < count; i++ {
1050
		fieldvar := v.newVariable("", uintptr(int64(v.Base)+(i*v.stride)), v.fieldType)
1051
		fieldvar.loadValueInternal(recurseLevel+1, cfg)
1052 1053

		if fieldvar.Unreadable != nil {
1054
			errcount++
E
epipho 已提交
1055
		}
1056

1057
		v.Children = append(v.Children, *fieldvar)
1058 1059 1060
		if errcount > maxErrCount {
			break
		}
1061 1062 1063
	}
}

1064
func (v *Variable) readComplex(size int64) {
1065 1066 1067 1068 1069 1070 1071
	var fs int64
	switch size {
	case 8:
		fs = 4
	case 16:
		fs = 8
	default:
1072 1073
		v.Unreadable = fmt.Errorf("invalid size (%d) for complex type", size)
		return
1074
	}
1075

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

1078 1079
	realvar := v.newVariable("real", v.Addr, ftyp)
	imagvar := v.newVariable("imaginary", v.Addr+uintptr(fs), ftyp)
1080 1081
	realvar.loadValue(loadSingleValue)
	imagvar.loadValue(loadSingleValue)
A
aarzilli 已提交
1082
	v.Value = constant.BinaryOp(realvar.Value, token.ADD, constant.MakeImag(imagvar.Value))
1083 1084
}

A
aarzilli 已提交
1085 1086
func (v *Variable) writeComplex(real, imag float64, size int64) error {
	err := v.writeFloatRaw(real, int64(size/2))
1087 1088 1089 1090 1091 1092 1093 1094
	if err != nil {
		return err
	}
	imagaddr := *v
	imagaddr.Addr += uintptr(size / 2)
	return imagaddr.writeFloatRaw(imag, int64(size/2))
}

1095
func readIntRaw(mem MemoryReadWriter, addr uintptr, size int64) (int64, error) {
E
epipho 已提交
1096
	var n int64
1097

1098 1099
	val := make([]byte, int(size))
	_, err := mem.ReadMemory(val, addr)
1100
	if err != nil {
D
Derek Parker 已提交
1101
		return 0, err
1102 1103
	}

1104 1105
	switch size {
	case 1:
1106
		n = int64(int8(val[0]))
1107
	case 2:
1108
		n = int64(int16(binary.LittleEndian.Uint16(val)))
1109
	case 4:
1110
		n = int64(int32(binary.LittleEndian.Uint32(val)))
1111
	case 8:
E
epipho 已提交
1112
		n = int64(binary.LittleEndian.Uint64(val))
1113
	}
1114

D
Derek Parker 已提交
1115
	return n, nil
E
epipho 已提交
1116 1117
}

A
aarzilli 已提交
1118
func (v *Variable) writeUint(value uint64, size int64) error {
1119 1120 1121 1122
	val := make([]byte, size)

	switch size {
	case 1:
A
aarzilli 已提交
1123
		val[0] = byte(value)
1124
	case 2:
A
aarzilli 已提交
1125
		binary.LittleEndian.PutUint16(val, uint16(value))
1126
	case 4:
A
aarzilli 已提交
1127
		binary.LittleEndian.PutUint32(val, uint32(value))
1128
	case 8:
A
aarzilli 已提交
1129
		binary.LittleEndian.PutUint64(val, uint64(value))
1130 1131
	}

1132
	_, err := v.mem.WriteMemory(v.Addr, val)
1133 1134 1135
	return err
}

1136
func readUintRaw(mem MemoryReadWriter, addr uintptr, size int64) (uint64, error) {
E
epipho 已提交
1137 1138
	var n uint64

1139 1140
	val := make([]byte, int(size))
	_, err := mem.ReadMemory(val, addr)
E
epipho 已提交
1141
	if err != nil {
D
Derek Parker 已提交
1142
		return 0, err
E
epipho 已提交
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
	}

	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 已提交
1156
	return n, nil
1157 1158
}

1159
func (v *Variable) readFloatRaw(size int64) (float64, error) {
1160 1161
	val := make([]byte, int(size))
	_, err := v.mem.ReadMemory(val, v.Addr)
1162
	if err != nil {
1163
		return 0.0, err
1164 1165 1166
	}
	buf := bytes.NewBuffer(val)

D
Derek Parker 已提交
1167 1168 1169 1170
	switch size {
	case 4:
		n := float32(0)
		binary.Read(buf, binary.LittleEndian, &n)
1171
		return float64(n), nil
D
Derek Parker 已提交
1172 1173 1174
	case 8:
		n := float64(0)
		binary.Read(buf, binary.LittleEndian, &n)
1175
		return n, nil
D
Derek Parker 已提交
1176 1177
	}

1178
	return 0.0, fmt.Errorf("could not read float")
1179 1180
}

1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192
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)
	}

1193
	_, err := v.mem.WriteMemory(v.Addr, buf.Bytes())
1194 1195 1196
	return err
}

A
aarzilli 已提交
1197
func (v *Variable) writeBool(value bool) error {
1198
	val := []byte{0}
A
aarzilli 已提交
1199
	val[0] = *(*byte)(unsafe.Pointer(&value))
1200
	_, err := v.mem.WriteMemory(v.Addr, val)
1201 1202 1203
	return err
}

1204
func (v *Variable) readFunctionPtr() {
1205
	val := make([]byte, v.bi.Arch.PtrSize())
1206
	_, err := v.mem.ReadMemory(val, v.Addr)
1207
	if err != nil {
1208 1209
		v.Unreadable = err
		return
1210 1211 1212
	}

	// dereference pointer to find function pc
1213 1214
	fnaddr := uintptr(binary.LittleEndian.Uint64(val))
	if fnaddr == 0 {
1215
		v.Base = 0
A
aarzilli 已提交
1216
		v.Value = constant.MakeString("")
1217
		return
1218
	}
1219

1220
	_, err = v.mem.ReadMemory(val, fnaddr)
1221
	if err != nil {
1222 1223
		v.Unreadable = err
		return
1224 1225
	}

1226
	v.Base = uintptr(binary.LittleEndian.Uint64(val))
1227
	fn := v.bi.goSymTable.PCToFunc(uint64(v.Base))
1228
	if fn == nil {
1229
		v.Unreadable = fmt.Errorf("could not find function for %#v", v.Base)
1230
		return
1231 1232
	}

1233
	v.Value = constant.MakeString(fn.Name)
1234 1235
}

1236
func (v *Variable) loadMap(recurseLevel int, cfg LoadConfig) {
A
aarzilli 已提交
1237 1238 1239 1240 1241 1242 1243
	it := v.mapIterator()
	if it == nil {
		return
	}

	for skip := 0; skip < v.mapSkip; skip++ {
		if ok := it.next(); !ok {
1244
			v.Unreadable = fmt.Errorf("map index out of bounds")
A
aarzilli 已提交
1245 1246 1247 1248 1249 1250 1251
			return
		}
	}

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

1300
	maptype, ok := sv.RealType.(*godwarf.StructType)
A
aarzilli 已提交
1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
	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
	}

1313
	v.mem = cacheMemory(v.mem, v.Base, int(v.RealType.Size()))
1314

A
aarzilli 已提交
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336
	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
		}
	}

1337 1338 1339 1340 1341
	if it.buckets.Kind != reflect.Struct || it.oldbuckets.Kind != reflect.Struct {
		v.Unreadable = mapBucketsNotStructErr
		return nil
	}

A
aarzilli 已提交
1342 1343 1344
	return it
}

1345 1346 1347 1348
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 已提交
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 1392 1393 1394 1395 1396 1397 1398 1399
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
	}

1400 1401
	it.b.mem = cacheMemory(it.b.mem, it.b.Addr, int(it.b.RealType.Size()))

A
aarzilli 已提交
1402 1403 1404 1405 1406
	it.tophashes = nil
	it.keys = nil
	it.values = nil
	it.overflow = nil

1407
	for _, f := range it.b.DwarfType.(*godwarf.StructType).Field {
A
aarzilli 已提交
1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436
		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 {
1437
		it.v.Unreadable = mapBucketContentsNotArrayErr
A
aarzilli 已提交
1438 1439 1440
		return false
	}

1441 1442 1443 1444 1445 1446 1447 1448
	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.
1449 1450 1451 1452 1453 1454
		it.v.Unreadable = mapBucketContentsInconsistentLenErr
		return false
	}

	if it.overflow.Kind != reflect.Struct {
		it.v.Unreadable = mapBucketsNotStructErr
A
aarzilli 已提交
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
		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
	}
1497
	for _, f := range b.DwarfType.(*godwarf.StructType).Field {
A
aarzilli 已提交
1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511
		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
}

1512
func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig) {
1513
	var _type, typestring, data *Variable
1514
	var typ godwarf.Type
A
Alessandro Arzilli 已提交
1515
	var err error
1516 1517
	isnil := false

A
Alessandro Arzilli 已提交
1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544
	// 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

1545 1546
	v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size()))

1547
	ityp := resolveTypedef(&v.RealType.(*godwarf.InterfaceType).TypedefType).(*godwarf.StructType)
1548 1549

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

	if isnil {
		// interface to nil
		data = data.maybeDereference()
		v.Children = []Variable{*data}
A
aarzilli 已提交
1589
		if loadData {
1590
			v.Children[0].loadValueInternal(recurseLevel, cfg)
A
aarzilli 已提交
1591
		}
1592 1593 1594
		return
	}

A
Alessandro Arzilli 已提交
1595
	if data == nil {
1596 1597 1598
		v.Unreadable = fmt.Errorf("invalid interface type")
		return
	}
A
Alessandro Arzilli 已提交
1599

1600 1601
	var kind int64

A
Alessandro Arzilli 已提交
1602 1603 1604
	if go17 {
		// No 'string' field use 'str' and 'runtime.firstmoduledata' to
		// find out what the concrete type is
1605
		_type = _type.maybeDereference()
A
Alessandro Arzilli 已提交
1606

1607 1608
		var typename string
		typename, kind, err = nameOfRuntimeType(_type)
A
Alessandro Arzilli 已提交
1609 1610 1611 1612 1613
		if err != nil {
			v.Unreadable = fmt.Errorf("invalid interface type: %v", err)
			return
		}

1614
		typ, err = v.bi.findType(typename)
A
Alessandro Arzilli 已提交
1615
		if err != nil {
1616
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
1617
			return
A
Alessandro Arzilli 已提交
1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629
		}
	} 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
		}

1630
		typename := constant.StringVal(typestring.Value)
1631

1632 1633 1634 1635 1636
		t, err := parser.ParseExpr(typename)
		if err != nil {
			v.Unreadable = fmt.Errorf("invalid interface type, unparsable data type: %v", err)
			return
		}
1637

1638
		typ, err = v.bi.findTypeExpr(t)
1639 1640 1641 1642
		if err != nil {
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
			return
		}
1643 1644
	}

1645
	deref := false
1646 1647
	if kind&kindDirectIface == 0 {
		realtyp := resolveTypedef(typ)
1648
		if _, isptr := realtyp.(*godwarf.PtrType); !isptr {
1649
			typ = pointerTo(typ, v.bi.Arch)
1650
			deref = true
1651
		}
1652 1653
	}

1654
	data = data.newVariable("data", data.Addr, typ)
1655 1656 1657 1658
	if deref {
		data = data.maybeDereference()
		data.Name = "data"
	}
1659 1660

	v.Children = []Variable{*data}
1661
	if loadData && recurseLevel <= cfg.MaxVariableRecurse {
1662 1663 1664
		v.Children[0].loadValueInternal(recurseLevel, cfg)
	} else {
		v.Children[0].OnlyAddr = true
1665 1666 1667
	}
}

E
epipho 已提交
1668
// Fetches all variables of a specific type in the current function scope
1669
func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg LoadConfig) ([]*Variable, error) {
1670
	reader := scope.DwarfReader()
1671
	off, err := scope.BinInfo.findFunctionDebugInfo(scope.PC)
1672
	if err != nil {
E
epipho 已提交
1673 1674
		return nil, err
	}
A
Alessandro Arzilli 已提交
1675 1676
	reader.Seek(off)
	reader.Next()
E
epipho 已提交
1677

D
Derek Parker 已提交
1678
	var vars []*Variable
1679
	for entry, err := reader.NextScopeVariable(); entry != nil; entry, err = reader.NextScopeVariable() {
E
epipho 已提交
1680 1681 1682
		if err != nil {
			return nil, err
		}
A
Alessandro Arzilli 已提交
1683 1684 1685
		if entry.Tag == 0 {
			break
		}
E
epipho 已提交
1686 1687

		if entry.Tag == tag {
1688
			val, err := scope.extractVariableFromEntry(entry, cfg)
E
epipho 已提交
1689
			if err != nil {
E
epipho 已提交
1690 1691
				// skip variables that we can't parse yet
				continue
E
epipho 已提交
1692 1693 1694 1695 1696
			}

			vars = append(vars, val)
		}
	}
A
Alessandro Arzilli 已提交
1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730
	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
		}
	}

1731 1732 1733 1734 1735 1736 1737
	for i, v := range vars {
		if name := v.Name; len(name) > 1 && name[0] == '&' {
			v = v.maybeDereference()
			v.Name = name[1:]
			v.Flags |= VariableEscaped
			vars[i] = v
		}
A
Alessandro Arzilli 已提交
1738 1739
		v.loadValue(cfg)
	}
E
epipho 已提交
1740 1741 1742

	return vars, nil
}