variables.go 46.6 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"
A
aarzilli 已提交
14
	"sort"
15 16 17
	"strings"
	"unsafe"

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

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

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

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

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

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

const (
	FloatIsNormal FloatSpecial = iota
	FloatIsNaN
	FloatIsPosInf
	FloatIsNegInf
)

44 45 46 47
type VariableFlags uint16

const (
	// VariableEscaped is set for local variables that escaped to the heap
48 49 50 51 52
	//
	// The compiler performs escape analysis on local variables, the variables
	// that may outlive the stack frame are allocated on the heap instead and
	// only the address is recorded on the stack. These variables will be
	// marked with this flag.
53
	VariableEscaped VariableFlags = (1 << iota)
A
aarzilli 已提交
54 55 56
	// VariableShadowed is set for local variables that are shadowed by a
	// variable with the same name in another scope
	VariableShadowed
57 58
)

D
Derek Parker 已提交
59 60 61 62
// 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.
63
type Variable struct {
64
	Addr      uintptr
A
aarzilli 已提交
65
	OnlyAddr  bool
66
	Name      string
67 68
	DwarfType godwarf.Type
	RealType  godwarf.Type
69
	Kind      reflect.Kind
70
	mem       MemoryReadWriter
71
	bi        *BinaryInfo
72

73 74
	Value        constant.Value
	FloatSpecial FloatSpecial
75 76 77 78

	Len int64
	Cap int64

79 80
	Flags VariableFlags

81 82
	// 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 已提交
83
	// address of the struct backing chan and map variables
A
aarzilli 已提交
84
	// address of the function entry point for function variables (0 for nil function pointers)
85
	Base      uintptr
86
	stride    int64
87
	fieldType godwarf.Type
88

A
aarzilli 已提交
89 90 91
	// number of elements to skip when loading a map
	mapSkip int

92 93 94 95
	Children []Variable

	loaded     bool
	Unreadable error
96 97
}

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
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 已提交
114
// G status, from: src/runtime/runtime2.go
115
const (
D
Derek Parker 已提交
116 117 118 119 120 121 122 123 124
	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
125 126
)

D
Derek Parker 已提交
127
// G represents a runtime G (goroutine) structure (at least the
128
// fields that Delve is interested in).
D
Derek Parker 已提交
129
type G struct {
D
Derek Parker 已提交
130
	ID         int    // Goroutine ID
131 132
	PC         uint64 // PC of goroutine when it was parked.
	SP         uint64 // SP of goroutine when it was parked.
133
	BP         uint64 // BP of goroutine when it was parked (go >= 1.7).
134 135
	GoPC       uint64 // PC of 'go' statement that created this goroutine.
	WaitReason string // Reason for goroutine being parked.
136
	Status     uint64
A
Alessandro Arzilli 已提交
137 138
	stkbarVar  *Variable // stkbar field of g struct
	stkbarPos  int       // stkbarPos field of g struct
139
	stackhi    uint64    // value of stack.hi
140

141
	// Information on goroutine location
142
	CurrentLoc Location
143

A
aarzilli 已提交
144
	// Thread that this goroutine is currently allocated to
145
	Thread Thread
146

A
Alessandro Arzilli 已提交
147
	variable *Variable
148 149
}

D
Derek Parker 已提交
150 151
// EvalScope is the scope for variable evaluation. Contains the thread,
// current location (PC), and canonical frame address.
152
type EvalScope struct {
153 154 155 156 157
	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
158
	StackHi uint64
159 160
}

D
Derek Parker 已提交
161
// IsNilErr is returned when a variable is nil.
162 163 164 165 166 167 168 169
type IsNilErr struct {
	name string
}

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

170
func (scope *EvalScope) newVariable(name string, addr uintptr, dwarfType godwarf.Type) *Variable {
171
	return newVariable(name, addr, dwarfType, scope.BinInfo, scope.Mem)
172 173
}

174
func newVariableFromThread(t Thread, name string, addr uintptr, dwarfType godwarf.Type) *Variable {
175
	return newVariable(name, addr, dwarfType, t.BinInfo(), t)
176 177
}

178
func (v *Variable) newVariable(name string, addr uintptr, dwarfType godwarf.Type) *Variable {
179
	return newVariable(name, addr, dwarfType, v.bi, v.mem)
180 181
}

182
func newVariable(name string, addr uintptr, dwarfType godwarf.Type, bi *BinaryInfo, mem MemoryReadWriter) *Variable {
183 184 185
	v := &Variable{
		Name:      name,
		Addr:      addr,
186
		DwarfType: dwarfType,
187
		mem:       mem,
188
		bi:        bi,
189 190
	}

191
	v.RealType = resolveTypedef(v.DwarfType)
192 193

	switch t := v.RealType.(type) {
194
	case *godwarf.PtrType:
195
		v.Kind = reflect.Ptr
196
		if _, isvoid := t.Type.(*godwarf.VoidType); isvoid {
197
			v.Kind = reflect.UnsafePointer
198
		}
199
	case *godwarf.ChanType:
200
		v.Kind = reflect.Chan
A
aarzilli 已提交
201 202 203
		if v.Addr != 0 {
			v.loadChanInfo()
		}
204
	case *godwarf.MapType:
205
		v.Kind = reflect.Map
206
	case *godwarf.StringType:
207 208
		v.Kind = reflect.String
		v.stride = 1
209
		v.fieldType = &godwarf.UintType{BasicType: godwarf.BasicType{CommonType: godwarf.CommonType{ByteSize: 1, Name: "byte"}, BitSize: 8, BitOffset: 0}}
210
		if v.Addr != 0 {
211
			v.Base, v.Len, v.Unreadable = readStringInfo(v.mem, v.bi.Arch, v.Addr)
212
		}
213
	case *godwarf.SliceType:
214 215 216 217
		v.Kind = reflect.Slice
		if v.Addr != 0 {
			v.loadSliceInfo(t)
		}
218
	case *godwarf.InterfaceType:
219
		v.Kind = reflect.Interface
220
	case *godwarf.StructType:
221
		v.Kind = reflect.Struct
222
	case *godwarf.ArrayType:
223
		v.Kind = reflect.Array
224
		v.Base = v.Addr
225 226 227 228 229 230 231 232
		v.Len = t.Count
		v.Cap = -1
		v.fieldType = t.Type
		v.stride = 0

		if t.Count > 0 {
			v.stride = t.ByteSize / t.Count
		}
233
	case *godwarf.ComplexType:
234 235 236 237 238 239
		switch t.ByteSize {
		case 8:
			v.Kind = reflect.Complex64
		case 16:
			v.Kind = reflect.Complex128
		}
240
	case *godwarf.IntType:
241
		v.Kind = reflect.Int
242
	case *godwarf.UintType:
243
		v.Kind = reflect.Uint
244
	case *godwarf.FloatType:
245 246 247 248 249 250
		switch t.ByteSize {
		case 4:
			v.Kind = reflect.Float32
		case 8:
			v.Kind = reflect.Float64
		}
251
	case *godwarf.BoolType:
252
		v.Kind = reflect.Bool
253
	case *godwarf.FuncType:
254
		v.Kind = reflect.Func
255
	case *godwarf.VoidType:
256
		v.Kind = reflect.Invalid
257
	case *godwarf.UnspecifiedType:
258 259 260
		v.Kind = reflect.Invalid
	default:
		v.Unreadable = fmt.Errorf("Unknown type: %T", t)
261 262
	}

263 264 265
	return v
}

266
func resolveTypedef(typ godwarf.Type) godwarf.Type {
267
	for {
268
		if tt, ok := typ.(*godwarf.TypedefType); ok {
269 270 271 272 273 274 275
			typ = tt.Type
		} else {
			return typ
		}
	}
}

276
func newConstant(val constant.Value, mem MemoryReadWriter) *Variable {
277
	v := &Variable{Value: val, mem: mem, loaded: true}
A
aarzilli 已提交
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
	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{
295
	Name:     "nil",
A
aarzilli 已提交
296
	Addr:     0,
297
	Base:     0,
A
aarzilli 已提交
298 299 300 301
	Kind:     reflect.Ptr,
	Children: []Variable{{Addr: 0, OnlyAddr: true}},
}

302 303 304
func (v *Variable) clone() *Variable {
	r := *v
	return &r
305 306
}

D
Derek Parker 已提交
307 308
// TypeString returns the string representation
// of the type of this variable.
309 310 311 312 313
func (v *Variable) TypeString() string {
	if v == nilVariable {
		return "nil"
	}
	if v.DwarfType != nil {
314
		return v.DwarfType.Common().Name
315 316 317 318
	}
	return v.Kind.String()
}

319
func (v *Variable) toField(field *godwarf.StructField) (*Variable, error) {
320 321 322
	if v.Unreadable != nil {
		return v.clone(), nil
	}
D
Derek Parker 已提交
323
	if v.Addr == 0 {
324
		return nil, &IsNilErr{v.Name}
D
Derek Parker 已提交
325 326
	}

327 328
	name := ""
	if v.Name != "" {
329 330 331 332
		parts := strings.Split(field.Name, ".")
		if len(parts) > 1 {
			name = fmt.Sprintf("%s.%s", v.Name, parts[1])
		} else {
D
Derek Parker 已提交
333
			name = fmt.Sprintf("%s.%s", v.Name, field.Name)
334
		}
335
	}
336
	return v.newVariable(name, uintptr(int64(v.Addr)+field.ByteOffset), field.Type), nil
337 338
}

D
Derek Parker 已提交
339 340
// DwarfReader returns the DwarfReader containing the
// Dwarf information for the target process.
341
func (scope *EvalScope) DwarfReader() *reader.Reader {
342
	return scope.BinInfo.DwarfReader()
343 344
}

D
Derek Parker 已提交
345
// Type returns the Dwarf type entry at `offset`.
346 347
func (scope *EvalScope) Type(offset dwarf.Offset) (godwarf.Type, error) {
	return godwarf.ReadType(scope.BinInfo.dwarf, offset, scope.BinInfo.typeCache)
348 349
}

D
Derek Parker 已提交
350
// PtrSize returns the size of a pointer.
351
func (scope *EvalScope) PtrSize() int {
352
	return scope.BinInfo.Arch.PtrSize()
353 354
}

A
aarzilli 已提交
355
// ChanRecvBlocked returns whether the goroutine is blocked on
356
// a channel read operation.
357
func (g *G) ChanRecvBlocked() bool {
358
	return (g.Thread == nil) && (g.WaitReason == chanRecv)
D
Derek Parker 已提交
359 360
}

D
Derek Parker 已提交
361 362
// NoGError returned when a G could not be found
// for a specific thread.
363 364 365 366 367 368 369 370
type NoGError struct {
	tid int
}

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

371 372 373
func (gvar *Variable) parseG() (*G, error) {
	mem := gvar.mem
	gaddr := uint64(gvar.Addr)
374
	_, deref := gvar.RealType.(*godwarf.PtrType)
375

376
	if deref {
377
		gaddrbytes := make([]byte, gvar.bi.Arch.PtrSize())
378
		_, err := mem.ReadMemory(gaddrbytes, uintptr(gaddr))
379 380 381 382
		if err != nil {
			return nil, fmt.Errorf("error derefing *G %s", err)
		}
		gaddr = binary.LittleEndian.Uint64(gaddrbytes)
383
	}
D
Derek Parker 已提交
384
	if gaddr == 0 {
385
		id := 0
386
		if thread, ok := mem.(Thread); ok {
387
			id = thread.ThreadID()
388
		}
A
Alessandro Arzilli 已提交
389
		return nil, NoGError{tid: id}
390
	}
A
Alessandro Arzilli 已提交
391
	for {
392
		if _, isptr := gvar.RealType.(*godwarf.PtrType); !isptr {
A
Alessandro Arzilli 已提交
393 394 395 396
			break
		}
		gvar = gvar.maybeDereference()
	}
397
	gvar.loadValue(LoadConfig{false, 2, 64, 0, -1})
D
Derek Parker 已提交
398 399
	if gvar.Unreadable != nil {
		return nil, gvar.Unreadable
400
	}
A
Alessandro Arzilli 已提交
401 402 403
	schedVar := gvar.fieldVariable("sched")
	pc, _ := constant.Int64Val(schedVar.fieldVariable("pc").Value)
	sp, _ := constant.Int64Val(schedVar.fieldVariable("sp").Value)
404 405 406 407
	var bp int64
	if bpvar := schedVar.fieldVariable("bp"); bpvar != nil && bpvar.Value != nil {
		bp, _ = constant.Int64Val(bpvar.Value)
	}
A
Alessandro Arzilli 已提交
408 409
	id, _ := constant.Int64Val(gvar.fieldVariable("goid").Value)
	gopc, _ := constant.Int64Val(gvar.fieldVariable("gopc").Value)
410 411 412 413
	waitReason := ""
	if wrvar := gvar.fieldVariable("waitreason"); wrvar.Value != nil {
		waitReason = constant.StringVal(wrvar.Value)
	}
414 415 416 417 418 419
	var stackhi uint64
	if stackVar := gvar.fieldVariable("stack"); stackVar != nil {
		if stackhiVar := stackVar.fieldVariable("hi"); stackhiVar != nil {
			stackhi, _ = constant.Uint64Val(stackhiVar.Value)
		}
	}
420

A
Alessandro Arzilli 已提交
421
	stkbarVar, _ := gvar.structMember("stkbar")
422 423 424 425 426 427
	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 已提交
428
	status, _ := constant.Int64Val(gvar.fieldVariable("atomicstatus").Value)
429
	f, l, fn := gvar.bi.PCToLine(uint64(pc))
D
Derek Parker 已提交
430 431 432 433 434
	g := &G{
		ID:         int(id),
		GoPC:       uint64(gopc),
		PC:         uint64(pc),
		SP:         uint64(sp),
435
		BP:         uint64(bp),
D
Derek Parker 已提交
436 437 438
		WaitReason: waitReason,
		Status:     uint64(status),
		CurrentLoc: Location{PC: uint64(pc), File: f, Line: l, Fn: fn},
A
Alessandro Arzilli 已提交
439
		variable:   gvar,
A
Alessandro Arzilli 已提交
440 441
		stkbarVar:  stkbarVar,
		stkbarPos:  int(stkbarPos),
442
		stackhi:    stackhi,
443
	}
D
Derek Parker 已提交
444 445
	return g, nil
}
446

A
Alessandro Arzilli 已提交
447
func (v *Variable) loadFieldNamed(name string) *Variable {
D
Derek Parker 已提交
448
	v, err := v.structMember(name)
449
	if err != nil {
D
Derek Parker 已提交
450
		return nil
451
	}
452
	v.loadValue(loadFullValue)
D
Derek Parker 已提交
453 454
	if v.Unreadable != nil {
		return nil
455
	}
D
Derek Parker 已提交
456
	return v
457 458
}

A
Alessandro Arzilli 已提交
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
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)
}

493 494 495 496 497 498 499 500
// 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 已提交
501 502
// UserCurrent returns the location the users code is at,
// or was at before entering a runtime function.
503
func (g *G) UserCurrent() Location {
A
aarzilli 已提交
504 505 506
	it, err := g.stackIterator()
	if err != nil {
		return g.CurrentLoc
507 508 509
	}
	for it.Next() {
		frame := it.Frame()
510 511
		if frame.Call.Fn != nil {
			name := frame.Call.Fn.Name
512
			if strings.Contains(name, ".") && (!strings.HasPrefix(name, "runtime.") || isExportedRuntime(name)) {
513 514
				return frame.Call
			}
515 516
		}
	}
517
	return g.CurrentLoc
518 519
}

D
Derek Parker 已提交
520 521
// Go returns the location of the 'go' statement
// that spawned this goroutine.
522
func (g *G) Go() Location {
523
	f, l, fn := g.variable.bi.PCToLine(g.GoPC)
524 525 526
	return Location{PC: g.GoPC, File: f, Line: l, Fn: fn}
}

A
Alessandro Arzilli 已提交
527 528
// Returns the list of saved return addresses used by stack barriers
func (g *G) stkbar() ([]savedLR, error) {
529 530 531
	if g.stkbarVar == nil { // stack barriers were removed in Go 1.9
		return nil, nil
	}
A
Alessandro Arzilli 已提交
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
	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 已提交
552
// EvalVariable returns the value of the given expression (backwards compatibility).
553 554
func (scope *EvalScope) EvalVariable(name string, cfg LoadConfig) (*Variable, error) {
	return scope.EvalExpression(name, cfg)
A
aarzilli 已提交
555
}
556

D
Derek Parker 已提交
557
// SetVariable sets the value of the named variable
A
aarzilli 已提交
558 559
func (scope *EvalScope) SetVariable(name, value string) error {
	t, err := parser.ParseExpr(name)
560
	if err != nil {
A
aarzilli 已提交
561
		return err
562 563
	}

A
aarzilli 已提交
564
	xv, err := scope.evalAST(t)
565
	if err != nil {
A
aarzilli 已提交
566
		return err
567
	}
568

A
aarzilli 已提交
569 570 571 572 573 574 575 576 577
	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)
578 579 580
	if err != nil {
		return err
	}
A
aarzilli 已提交
581 582 583 584 585 586

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

587
	yv.loadValue(loadSingleValue)
A
aarzilli 已提交
588 589 590

	if err := yv.isType(xv.RealType, xv.Kind); err != nil {
		return err
591
	}
A
aarzilli 已提交
592 593 594 595 596 597

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

	return xv.setValue(yv)
598 599
}

A
aarzilli 已提交
600 601
func (scope *EvalScope) extractVariableFromEntry(entry *dwarf.Entry) (*Variable, error) {
	v, err := scope.extractVarInfoFromEntry(entry)
602
	if err != nil {
D
Derek Parker 已提交
603 604
		return nil, err
	}
605
	return v, nil
606
}
D
Derek Parker 已提交
607

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

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

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

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

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

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

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

	return vars, nil
}

650
func (scope *EvalScope) packageVarAddr(name string) (*Variable, error) {
651
	for n, off := range scope.BinInfo.packageVars {
652
		if n == name || strings.HasSuffix(n, "/"+name) {
653 654 655 656 657 658
			reader := scope.DwarfReader()
			reader.Seek(off)
			entry, err := reader.Next()
			if err != nil {
				return nil, err
			}
A
aarzilli 已提交
659
			return scope.extractVarInfoFromEntry(entry)
660 661 662 663 664
		}
	}
	return nil, fmt.Errorf("could not find symbol value for %s", name)
}

665
func (v *Variable) structMember(memberName string) (*Variable, error) {
666 667 668
	if v.Unreadable != nil {
		return v.clone(), nil
	}
A
aarzilli 已提交
669 670 671 672 673
	switch v.Kind {
	case reflect.Chan:
		v = v.clone()
		v.RealType = resolveTypedef(&(v.RealType.(*godwarf.ChanType).TypedefType))
	}
674
	structVar := v.maybeDereference()
675
	structVar.Name = v.Name
676 677
	if structVar.Unreadable != nil {
		return structVar, nil
678
	}
679 680

	switch t := structVar.RealType.(type) {
681
	case *godwarf.StructType:
682 683 684
		for _, field := range t.Field {
			if field.Name != memberName {
				continue
685
			}
L
Luke Hoban 已提交
686
			return structVar.toField(field)
687 688 689 690 691
		}
		// Check for embedded field only if field was
		// not a regular struct member
		for _, field := range t.Field {
			isEmbeddedStructMember :=
692 693
				field.Embedded ||
					(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
			if err != nil {
				return nil, err
			}
			embeddedVar.Name = structVar.Name
715
			embeddedField, _ := embeddedVar.structMember(memberName)
716 717
			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
// 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
A
aarzilli 已提交
731
func (scope *EvalScope) extractVarInfoFromEntry(entry *dwarf.Entry) (*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(op.DwarfRegisters{CFA: 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 *godwarf.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
		sv := v.clone()
817
		sv.RealType = resolveTypedef(&(sv.RealType.(*godwarf.ChanType).TypedefType))
818
		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)
827 828 829
		} else {
			// loads length so that the client knows that the map isn't empty
			v.mapIterator()
A
aarzilli 已提交
830
		}
A
aarzilli 已提交
831

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

	case reflect.Slice, reflect.Array:
838
		v.loadArrayValues(recurseLevel, cfg)
839 840

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

859
	case reflect.Interface:
860
		v.loadInterface(recurseLevel, true, cfg)
861

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

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

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

	return err
926 927
}

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

932 933
	mem = cacheMemory(mem, addr, arch.PtrSize()*2)

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

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

A
aarzilli 已提交
955 956 957
	return addr, strlen, nil
}

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

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

970 971
	retstr := *(*string)(unsafe.Pointer(&val))

A
aarzilli 已提交
972 973 974
	return retstr, nil
}

975
func (v *Variable) loadSliceInfo(t *godwarf.SliceType) {
976 977
	v.mem = cacheMemory(v.mem, v.Addr, int(t.Size()))

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

1015
	v.stride = v.fieldType.Size()
1016
	if t, ok := v.fieldType.(*godwarf.PtrType); ok {
1017
		v.stride = t.ByteSize
1018 1019 1020
	}
}

A
aarzilli 已提交
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
// loadChanInfo loads the buffer size of the channel and changes the type of
// the buf field from unsafe.Pointer to an array of the correct type.
func (v *Variable) loadChanInfo() {
	chanType, ok := v.RealType.(*godwarf.ChanType)
	if !ok {
		v.Unreadable = errors.New("bad channel type")
		return
	}
	sv := v.clone()
	sv.RealType = resolveTypedef(&(chanType.TypedefType))
	sv = sv.maybeDereference()
	if sv.Unreadable != nil || sv.Addr == 0 {
		return
	}
	structType, ok := sv.DwarfType.(*godwarf.StructType)
	if !ok {
		v.Unreadable = errors.New("bad channel type")
		return
	}

	lenAddr, _ := sv.toField(structType.Field[1])
	lenAddr.loadValue(loadSingleValue)
	if lenAddr.Unreadable != nil {
		v.Unreadable = fmt.Errorf("unreadable length: %v", lenAddr.Unreadable)
		return
	}
	chanLen, _ := constant.Uint64Val(lenAddr.Value)

	newStructType := &godwarf.StructType{}
	*newStructType = *structType
	newStructType.Field = make([]*godwarf.StructField, len(structType.Field))

	for i := range structType.Field {
		field := &godwarf.StructField{}
		*field = *structType.Field[i]
		if field.Name == "buf" {
			stride := chanType.ElemType.Common().ByteSize
			atyp := &godwarf.ArrayType{
				CommonType: godwarf.CommonType{
					ReflectKind: reflect.Array,
					ByteSize:    int64(chanLen) * stride,
					Name:        fmt.Sprintf("[%d]%s", chanLen, chanType.ElemType.String())},
				Type:          chanType.ElemType,
				StrideBitSize: stride * 8,
				Count:         int64(chanLen)}

			field.Type = pointerTo(atyp, v.bi.Arch)
		}
		newStructType.Field[i] = field
	}

	v.RealType = &godwarf.ChanType{
		TypedefType: godwarf.TypedefType{
			CommonType: chanType.TypedefType.CommonType,
			Type:       pointerTo(newStructType, v.bi.Arch),
		},
		ElemType: chanType.ElemType,
	}
}

1081
func (v *Variable) loadArrayValues(recurseLevel int, cfg LoadConfig) {
1082 1083 1084
	if v.Unreadable != nil {
		return
	}
1085 1086 1087 1088
	if v.Len < 0 {
		v.Unreadable = errors.New("Negative array length")
		return
	}
1089

1090 1091
	count := v.Len
	// Cap number of elements
1092 1093
	if count > int64(cfg.MaxArrayValues) {
		count = int64(cfg.MaxArrayValues)
1094
	}
1095

1096
	if v.stride < maxArrayStridePrefetch {
1097
		v.mem = cacheMemory(v.mem, v.Base, int(v.stride*count))
1098
	}
1099

1100 1101 1102
	errcount := 0

	for i := int64(0); i < count; i++ {
1103
		fieldvar := v.newVariable("", uintptr(int64(v.Base)+(i*v.stride)), v.fieldType)
1104
		fieldvar.loadValueInternal(recurseLevel+1, cfg)
1105 1106

		if fieldvar.Unreadable != nil {
1107
			errcount++
E
epipho 已提交
1108
		}
1109

1110
		v.Children = append(v.Children, *fieldvar)
1111 1112 1113
		if errcount > maxErrCount {
			break
		}
1114 1115 1116
	}
}

1117
func (v *Variable) readComplex(size int64) {
1118 1119 1120 1121 1122 1123 1124
	var fs int64
	switch size {
	case 8:
		fs = 4
	case 16:
		fs = 8
	default:
1125 1126
		v.Unreadable = fmt.Errorf("invalid size (%d) for complex type", size)
		return
1127
	}
1128

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

1131 1132
	realvar := v.newVariable("real", v.Addr, ftyp)
	imagvar := v.newVariable("imaginary", v.Addr+uintptr(fs), ftyp)
1133 1134
	realvar.loadValue(loadSingleValue)
	imagvar.loadValue(loadSingleValue)
A
aarzilli 已提交
1135
	v.Value = constant.BinaryOp(realvar.Value, token.ADD, constant.MakeImag(imagvar.Value))
1136 1137
}

A
aarzilli 已提交
1138 1139
func (v *Variable) writeComplex(real, imag float64, size int64) error {
	err := v.writeFloatRaw(real, int64(size/2))
1140 1141 1142 1143 1144 1145 1146 1147
	if err != nil {
		return err
	}
	imagaddr := *v
	imagaddr.Addr += uintptr(size / 2)
	return imagaddr.writeFloatRaw(imag, int64(size/2))
}

1148
func readIntRaw(mem MemoryReadWriter, addr uintptr, size int64) (int64, error) {
E
epipho 已提交
1149
	var n int64
1150

1151 1152
	val := make([]byte, int(size))
	_, err := mem.ReadMemory(val, addr)
1153
	if err != nil {
D
Derek Parker 已提交
1154
		return 0, err
1155 1156
	}

1157 1158
	switch size {
	case 1:
1159
		n = int64(int8(val[0]))
1160
	case 2:
1161
		n = int64(int16(binary.LittleEndian.Uint16(val)))
1162
	case 4:
1163
		n = int64(int32(binary.LittleEndian.Uint32(val)))
1164
	case 8:
E
epipho 已提交
1165
		n = int64(binary.LittleEndian.Uint64(val))
1166
	}
1167

D
Derek Parker 已提交
1168
	return n, nil
E
epipho 已提交
1169 1170
}

A
aarzilli 已提交
1171
func (v *Variable) writeUint(value uint64, size int64) error {
1172 1173 1174 1175
	val := make([]byte, size)

	switch size {
	case 1:
A
aarzilli 已提交
1176
		val[0] = byte(value)
1177
	case 2:
A
aarzilli 已提交
1178
		binary.LittleEndian.PutUint16(val, uint16(value))
1179
	case 4:
A
aarzilli 已提交
1180
		binary.LittleEndian.PutUint32(val, uint32(value))
1181
	case 8:
A
aarzilli 已提交
1182
		binary.LittleEndian.PutUint64(val, uint64(value))
1183 1184
	}

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

1189
func readUintRaw(mem MemoryReadWriter, addr uintptr, size int64) (uint64, error) {
E
epipho 已提交
1190 1191
	var n uint64

1192 1193
	val := make([]byte, int(size))
	_, err := mem.ReadMemory(val, addr)
E
epipho 已提交
1194
	if err != nil {
D
Derek Parker 已提交
1195
		return 0, err
E
epipho 已提交
1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
	}

	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 已提交
1209
	return n, nil
1210 1211
}

1212
func (v *Variable) readFloatRaw(size int64) (float64, error) {
1213 1214
	val := make([]byte, int(size))
	_, err := v.mem.ReadMemory(val, v.Addr)
1215
	if err != nil {
1216
		return 0.0, err
1217 1218 1219
	}
	buf := bytes.NewBuffer(val)

D
Derek Parker 已提交
1220 1221 1222 1223
	switch size {
	case 4:
		n := float32(0)
		binary.Read(buf, binary.LittleEndian, &n)
1224
		return float64(n), nil
D
Derek Parker 已提交
1225 1226 1227
	case 8:
		n := float64(0)
		binary.Read(buf, binary.LittleEndian, &n)
1228
		return n, nil
D
Derek Parker 已提交
1229 1230
	}

1231
	return 0.0, fmt.Errorf("could not read float")
1232 1233
}

1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245
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)
	}

1246
	_, err := v.mem.WriteMemory(v.Addr, buf.Bytes())
1247 1248 1249
	return err
}

A
aarzilli 已提交
1250
func (v *Variable) writeBool(value bool) error {
1251
	val := []byte{0}
A
aarzilli 已提交
1252
	val[0] = *(*byte)(unsafe.Pointer(&value))
1253
	_, err := v.mem.WriteMemory(v.Addr, val)
1254 1255 1256
	return err
}

1257
func (v *Variable) readFunctionPtr() {
1258
	val := make([]byte, v.bi.Arch.PtrSize())
1259
	_, err := v.mem.ReadMemory(val, v.Addr)
1260
	if err != nil {
1261 1262
		v.Unreadable = err
		return
1263 1264 1265
	}

	// dereference pointer to find function pc
1266 1267
	fnaddr := uintptr(binary.LittleEndian.Uint64(val))
	if fnaddr == 0 {
1268
		v.Base = 0
A
aarzilli 已提交
1269
		v.Value = constant.MakeString("")
1270
		return
1271
	}
1272

1273
	_, err = v.mem.ReadMemory(val, fnaddr)
1274
	if err != nil {
1275 1276
		v.Unreadable = err
		return
1277 1278
	}

1279
	v.Base = uintptr(binary.LittleEndian.Uint64(val))
1280
	fn := v.bi.PCToFunc(uint64(v.Base))
1281
	if fn == nil {
1282
		v.Unreadable = fmt.Errorf("could not find function for %#v", v.Base)
1283
		return
1284 1285
	}

1286
	v.Value = constant.MakeString(fn.Name)
1287 1288
}

1289
func (v *Variable) loadMap(recurseLevel int, cfg LoadConfig) {
A
aarzilli 已提交
1290 1291 1292 1293 1294 1295 1296
	it := v.mapIterator()
	if it == nil {
		return
	}

	for skip := 0; skip < v.mapSkip; skip++ {
		if ok := it.next(); !ok {
1297
			v.Unreadable = fmt.Errorf("map index out of bounds")
A
aarzilli 已提交
1298 1299 1300 1301 1302 1303 1304
			return
		}
	}

	count := 0
	errcount := 0
	for it.next() {
1305
		if count >= cfg.MaxArrayValues {
A
aarzilli 已提交
1306 1307 1308
			break
		}
		key := it.key()
1309 1310 1311 1312 1313 1314
		var val *Variable
		if it.values.fieldType.Size() > 0 {
			val = it.value()
		} else {
			val = v.newVariable("", it.values.Addr, it.values.fieldType)
		}
1315 1316
		key.loadValueInternal(recurseLevel+1, cfg)
		val.loadValueInternal(recurseLevel+1, cfg)
A
aarzilli 已提交
1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
		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 {
1348
	sv := v.clone()
1349
	sv.RealType = resolveTypedef(&(sv.RealType.(*godwarf.MapType).TypedefType))
1350
	sv = sv.maybeDereference()
1351
	v.Base = sv.Addr
A
aarzilli 已提交
1352

1353
	maptype, ok := sv.RealType.(*godwarf.StructType)
A
aarzilli 已提交
1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365
	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
	}

1366
	v.mem = cacheMemory(v.mem, v.Base, int(v.RealType.Size()))
1367

A
aarzilli 已提交
1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389
	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
		}
	}

1390 1391 1392 1393 1394
	if it.buckets.Kind != reflect.Struct || it.oldbuckets.Kind != reflect.Struct {
		v.Unreadable = mapBucketsNotStructErr
		return nil
	}

A
aarzilli 已提交
1395 1396 1397
	return it
}

1398 1399 1400 1401
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 已提交
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 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452
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
	}

1453 1454
	it.b.mem = cacheMemory(it.b.mem, it.b.Addr, int(it.b.RealType.Size()))

A
aarzilli 已提交
1455 1456 1457 1458 1459
	it.tophashes = nil
	it.keys = nil
	it.values = nil
	it.overflow = nil

1460
	for _, f := range it.b.DwarfType.(*godwarf.StructType).Field {
A
aarzilli 已提交
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
		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 {
1490
		it.v.Unreadable = mapBucketContentsNotArrayErr
A
aarzilli 已提交
1491 1492 1493
		return false
	}

1494 1495 1496 1497 1498 1499 1500 1501
	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.
1502 1503 1504 1505 1506 1507
		it.v.Unreadable = mapBucketContentsInconsistentLenErr
		return false
	}

	if it.overflow.Kind != reflect.Struct {
		it.v.Unreadable = mapBucketsNotStructErr
A
aarzilli 已提交
1508 1509 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 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
		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
	}
1550
	for _, f := range b.DwarfType.(*godwarf.StructType).Field {
A
aarzilli 已提交
1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564
		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
}

1565
func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig) {
1566
	var _type, typestring, data *Variable
1567
	var typ godwarf.Type
A
Alessandro Arzilli 已提交
1568
	var err error
1569 1570
	isnil := false

A
Alessandro Arzilli 已提交
1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597
	// 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

1598 1599
	v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size()))

1600
	ityp := resolveTypedef(&v.RealType.(*godwarf.InterfaceType).TypedefType).(*godwarf.StructType)
1601 1602

	for _, f := range ityp.Field {
1603 1604 1605
		switch f.Name {
		case "tab": // for runtime.iface
			tab, _ := v.toField(f)
A
Alessandro Arzilli 已提交
1606 1607 1608 1609 1610
			tab = tab.maybeDereference()
			isnil = tab.Addr == 0
			if !isnil {
				_type, err = tab.structMember("_type")
				if err != nil {
1611 1612 1613 1614
					v.Unreadable = fmt.Errorf("invalid interface type: %v", err)
					return
				}
				typestring, err = _type.structMember("_string")
A
Alessandro Arzilli 已提交
1615 1616 1617 1618
				if err == nil {
					typestring = typestring.maybeDereference()
				} else {
					go17 = true
1619 1620 1621
				}
			}
		case "_type": // for runtime.eface
A
Alessandro Arzilli 已提交
1622 1623 1624 1625 1626 1627 1628 1629 1630
			_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
1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641
				}
			}
		case "data":
			data, _ = v.toField(f)
		}
	}

	if isnil {
		// interface to nil
		data = data.maybeDereference()
		v.Children = []Variable{*data}
A
aarzilli 已提交
1642
		if loadData {
1643
			v.Children[0].loadValueInternal(recurseLevel, cfg)
A
aarzilli 已提交
1644
		}
1645 1646 1647
		return
	}

A
Alessandro Arzilli 已提交
1648
	if data == nil {
1649 1650 1651
		v.Unreadable = fmt.Errorf("invalid interface type")
		return
	}
A
Alessandro Arzilli 已提交
1652

1653 1654
	var kind int64

A
Alessandro Arzilli 已提交
1655 1656 1657
	if go17 {
		// No 'string' field use 'str' and 'runtime.firstmoduledata' to
		// find out what the concrete type is
1658
		_type = _type.maybeDereference()
A
Alessandro Arzilli 已提交
1659

1660 1661
		var typename string
		typename, kind, err = nameOfRuntimeType(_type)
A
Alessandro Arzilli 已提交
1662 1663 1664 1665 1666
		if err != nil {
			v.Unreadable = fmt.Errorf("invalid interface type: %v", err)
			return
		}

1667
		typ, err = v.bi.findType(typename)
A
Alessandro Arzilli 已提交
1668
		if err != nil {
1669
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
1670
			return
A
Alessandro Arzilli 已提交
1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682
		}
	} 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
		}

1683
		typename := constant.StringVal(typestring.Value)
1684

1685 1686 1687 1688 1689
		t, err := parser.ParseExpr(typename)
		if err != nil {
			v.Unreadable = fmt.Errorf("invalid interface type, unparsable data type: %v", err)
			return
		}
1690

1691
		typ, err = v.bi.findTypeExpr(t)
1692 1693 1694 1695
		if err != nil {
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
			return
		}
1696 1697
	}

1698
	deref := false
1699 1700
	if kind&kindDirectIface == 0 {
		realtyp := resolveTypedef(typ)
1701
		if _, isptr := realtyp.(*godwarf.PtrType); !isptr {
1702
			typ = pointerTo(typ, v.bi.Arch)
1703
			deref = true
1704
		}
1705 1706
	}

1707
	data = data.newVariable("data", data.Addr, typ)
1708 1709 1710 1711
	if deref {
		data = data.maybeDereference()
		data.Name = "data"
	}
1712 1713

	v.Children = []Variable{*data}
1714
	if loadData && recurseLevel <= cfg.MaxVariableRecurse {
1715 1716 1717
		v.Children[0].loadValueInternal(recurseLevel, cfg)
	} else {
		v.Children[0].OnlyAddr = true
1718 1719 1720
	}
}

A
aarzilli 已提交
1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734
type variablesByDepth struct {
	vars   []*Variable
	depths []int
}

func (v *variablesByDepth) Len() int { return len(v.vars) }

func (v *variablesByDepth) Less(i int, j int) bool { return v.depths[i] < v.depths[j] }

func (v *variablesByDepth) Swap(i int, j int) {
	v.depths[i], v.depths[j] = v.depths[j], v.depths[i]
	v.vars[i], v.vars[j] = v.vars[j], v.vars[i]
}

E
epipho 已提交
1735
// Fetches all variables of a specific type in the current function scope
A
aarzilli 已提交
1736
func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg *LoadConfig) ([]*Variable, error) {
1737 1738 1739
	fn := scope.BinInfo.PCToFunc(scope.PC)
	if fn == nil {
		return nil, errors.New("unable to find function context")
E
epipho 已提交
1740 1741
	}

D
Derek Parker 已提交
1742
	var vars []*Variable
A
aarzilli 已提交
1743
	var depths []int
1744
	varReader := reader.Variables(scope.BinInfo.dwarf, fn.offset, scope.PC, tag == dwarf.TagVariable)
A
aarzilli 已提交
1745 1746 1747 1748 1749 1750 1751
	hasScopes := false
	for varReader.Next() {
		entry := varReader.Entry()
		if entry.Tag != tag {
			continue
		}
		val, err := scope.extractVariableFromEntry(entry)
E
epipho 已提交
1752
		if err != nil {
A
aarzilli 已提交
1753 1754
			// skip variables that we can't parse yet
			continue
E
epipho 已提交
1755
		}
A
aarzilli 已提交
1756 1757 1758 1759 1760
		vars = append(vars, val)
		depth := varReader.Depth()
		depths = append(depths, depth)
		if depth > 1 {
			hasScopes = true
A
Alessandro Arzilli 已提交
1761
		}
A
aarzilli 已提交
1762
	}
E
epipho 已提交
1763

A
aarzilli 已提交
1764 1765
	if err := varReader.Err(); err != nil {
		return nil, err
E
epipho 已提交
1766
	}
A
aarzilli 已提交
1767

A
Alessandro Arzilli 已提交
1768 1769 1770 1771
	if len(vars) <= 0 {
		return vars, nil
	}

A
aarzilli 已提交
1772 1773 1774 1775
	if hasScopes {
		sort.Stable(&variablesByDepth{vars, depths})
	}

A
Alessandro Arzilli 已提交
1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805
	// 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
		}
	}

A
aarzilli 已提交
1806 1807
	lvn := map[string]*Variable{} // lvn[n] is the last variable we saw named n

1808 1809 1810 1811 1812 1813 1814
	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
aarzilli 已提交
1815 1816 1817 1818 1819 1820 1821 1822 1823
		if hasScopes {
			if otherv := lvn[v.Name]; otherv != nil {
				otherv.Flags |= VariableShadowed
			}
			lvn[v.Name] = v
		}
		if cfg != nil {
			v.loadValue(*cfg)
		}
A
Alessandro Arzilli 已提交
1824
	}
E
epipho 已提交
1825 1826 1827

	return vars, nil
}