1// Copyright 2019 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14//m4_changequote(`@',`@') 15// Evaluates Go expressions, using the current values of variables in a program 16// being debugged. 17// 18// TODOs: 19// More overflow checking. 20// Stricter type checking. 21// More expression types. 22 23package server 24 25import ( 26 "errors" 27 "fmt" 28 "go/ast" 29 "go/parser" 30 "go/token" 31 "math" 32 "math/big" 33 34 "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" 35 "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" 36) 37 38const prec = 256 // precision for untyped float and complex constants. 39 40var ( 41 // Some big.Ints to use in overflow checks. 42 bigIntMaxInt32 = big.NewInt(math.MaxInt32) 43 bigIntMinInt32 = big.NewInt(math.MinInt32) 44 bigIntMaxInt64 = big.NewInt(math.MaxInt64) 45 bigIntMinInt64 = big.NewInt(math.MinInt64) 46 bigIntMaxUint64 = new(big.Int).SetUint64(math.MaxUint64) 47) 48 49// result stores an intermediate value produced during evaluation of an expression. 50// 51// d contains the DWARF type of the value. For untyped values, d will be nil. 52// 53// v contains the value itself. For numeric and bool types, v will have the 54// corresponding predeclared Go type. 55// For untyped integer, rune, float, complex, string, and bool constants, v will 56// have type untInt, untRune, untFloat, untComplex, untString, or bool, 57// respectively. 58// For values of type int, uint and uintptr, v will be an int32, int64, uint32 59// or uint64 as appropriate. 60// For address operations, v will have type pointerToValue. 61// For the operands of address operations, v will have type addressableValue. 62// Other types are represented using the corresponding implementation of 63// debug.Value in program.go. 64// 65// If an evaluation results in an error, the zero value of result is used. 66type result struct { 67 d dwarf.Type 68 v interface{} 69} 70 71// untInt is an untyped integer constant 72type untInt struct { 73 *big.Int 74} 75 76// untRune is an untyped rune constant 77type untRune struct { 78 *big.Int 79} 80 81// untFloat is an untyped floating-point constant 82type untFloat struct { 83 *big.Float 84} 85 86// untComplex is an untyped complex constant 87type untComplex struct { 88 r *big.Float 89 i *big.Float 90} 91 92// untString is an untyped string constant 93type untString string 94 95// pointerToValue is a pointer to a value in memory. 96// The evaluator constructs these as the result of address operations like "&x". 97// Unlike debug.Pointer, the DWARF type stored alongside values of this type 98// is the type of the variable, not the type of the pointer. 99type pointerToValue struct { 100 a uint64 101} 102 103// addressableValue is the memory location of a value. 104// The evaluator constructs these while evaluating the operands of address 105// operations like "&x", instead of computing the value of x itself. 106type addressableValue struct { 107 a uint64 108} 109 110// A sliceOf is a slice created by slicing an array. 111// Unlike debug.Slice, the DWARF type stored alongside a value of this type is 112// the type of the slice's elements, not the type of the slice. 113type sliceOf debug.Slice 114 115// ident is a value for representing a special identifier. 116type ident string 117 118// identLookup is a built-in function of the expression evaluator which gets the 119// value of a global symbol. 120var identLookup ident = "lookup" 121 122// evalExpression evaluates a Go expression. 123// If the program counter and stack pointer are nonzero, they are used to determine 124// what local variables are available and where in memory they are. 125func (s *Server) evalExpression(expression string, pc, sp uint64) (debug.Value, error) { 126 e := evaluator{server: s, expression: expression, pc: pc, sp: sp} 127 node, err := parser.ParseExpr(expression) 128 if err != nil { 129 return nil, err 130 } 131 val := e.evalNode(node, false) 132 if e.evalError != nil { 133 return nil, e.evalError 134 } 135 136 // Convert untyped constants to their default types. 137 switch v := val.v.(type) { 138 case untInt: 139 return e.intFromInteger(v) 140 case untRune: 141 if v.Cmp(bigIntMaxInt32) == +1 { 142 return nil, errors.New("constant overflows rune") 143 } 144 if v.Cmp(bigIntMinInt32) == -1 { 145 return nil, errors.New("constant overflows rune") 146 } 147 return int32(v.Int64()), nil 148 case untFloat: 149 f, _ := v.Float64() 150 if math.IsInf(f, 0) { 151 return nil, errors.New("constant overflows float64") 152 } 153 if math.IsNaN(f) { 154 return nil, errors.New("constant is NaN") 155 } 156 return f, nil 157 case untComplex: 158 r, _ := v.r.Float64() 159 i, _ := v.i.Float64() 160 if math.IsInf(r, 0) || math.IsInf(i, 0) { 161 return nil, errors.New("constant overflows complex128") 162 } 163 if math.IsNaN(r) || math.IsNaN(i) { 164 return nil, errors.New("constant is NaN") 165 } 166 return complex(r, i), nil 167 case untString: 168 return debug.String{Length: uint64(len(v)), String: string(v)}, nil 169 case pointerToValue: 170 return debug.Pointer{TypeID: uint64(val.d.Common().Offset), Address: v.a}, nil 171 case sliceOf: 172 return debug.Slice(v), nil 173 case nil, addressableValue: 174 // This case should not be reachable. 175 return nil, errors.New("unknown error") 176 } 177 return val.v, nil 178} 179 180type evaluator struct { 181 // expression is the expression being evaluated. 182 expression string 183 // server interacts with the program being debugged. 184 server *Server 185 // curNode is the current parse tree node. This is set so that error messages 186 // can quote the part of the expression that caused an error. 187 curNode ast.Node 188 // evalError is the first error that occurred while evaluating the expression, 189 // or nil if no error has occurred. 190 evalError error 191 // pc and sp are the current program counter and stack pointer, used for 192 // finding local variables. If either are zero, the expression is evaluated 193 // without using local variables. 194 pc uint64 195 sp uint64 196} 197 198// setNode sets curNode, and returns curNode's previous value. 199func (e *evaluator) setNode(node ast.Node) (old ast.Node) { 200 old, e.curNode = e.curNode, node 201 return old 202} 203 204// err saves an error that occurred during evaluation. 205// It returns a zero result, so that functions can exit and set an error with 206// return e.err(...) 207func (e *evaluator) err(s string) result { 208 if e.evalError != nil { 209 return result{} 210 } 211 // Append the substring of the expression that corresponds to the current AST node. 212 start := int(e.curNode.Pos() - 1) 213 end := int(e.curNode.End() - 1) 214 if start < 0 { 215 start = 0 216 } 217 if end > len(e.expression) { 218 end = len(e.expression) 219 } 220 if start > end { 221 start, end = 0, 0 222 } 223 e.evalError = errors.New(s + `: "` + e.expression[start:end] + `"`) 224 return result{} 225} 226 227// evalNode computes the value of a node in the expression tree. 228// If getAddress is true, the node is the argument of an & operator, so evalNode 229// will return a result with a value of type addressableValue if possible. 230func (e *evaluator) evalNode(node ast.Node, getAddress bool) result { 231 // Set the current node in the evaluator, so that error messages can refer to 232 // it. Defer a function call that changes it back. 233 defer e.setNode(e.setNode(node)) 234 235 switch n := node.(type) { 236 case *ast.Ident: 237 if e.pc != 0 && e.sp != 0 { 238 a, t := e.server.findLocalVar(n.Name, e.pc, e.sp) 239 if t != nil { 240 return e.resultFrom(a, t, getAddress) 241 } 242 } 243 a, t := e.server.findGlobalVar(n.Name) 244 if t != nil { 245 return e.resultFrom(a, t, getAddress) 246 } 247 switch n.Name { 248 // Note: these could have been redefined as constants in the code, but we 249 // don't have a way to detect that. 250 case "true": 251 return result{nil, true} 252 case "false": 253 return result{nil, false} 254 case "lookup": 255 return result{nil, identLookup} 256 } 257 return e.err("unknown identifier") 258 259 case *ast.BasicLit: 260 switch n.Kind { 261 case token.INT: 262 i := new(big.Int) 263 if _, ok := i.SetString(n.Value, 0); !ok { 264 return e.err("invalid integer constant") 265 } 266 return result{nil, untInt{i}} 267 case token.FLOAT: 268 r, _, err := big.ParseFloat(n.Value, 10, prec, big.ToNearestEven) 269 if err != nil { 270 return e.err(err.Error()) 271 } 272 return result{nil, untFloat{r}} 273 case token.IMAG: 274 if len(n.Value) <= 1 || n.Value[len(n.Value)-1] != 'i' { 275 return e.err("invalid imaginary constant") 276 } 277 r, _, err := big.ParseFloat(n.Value[:len(n.Value)-1], 10, prec, big.ToNearestEven) 278 if err != nil { 279 return e.err(err.Error()) 280 } 281 return result{nil, untComplex{new(big.Float), r}} 282 case token.CHAR: 283 // TODO: unescaping 284 return result{nil, untRune{new(big.Int).SetInt64(int64(n.Value[1]))}} 285 case token.STRING: 286 // TODO: unescaping 287 if len(n.Value) <= 1 { 288 return e.err("invalid string constant") 289 } 290 return result{nil, untString(n.Value[1 : len(n.Value)-1])} 291 } 292 293 case *ast.ParenExpr: 294 return e.evalNode(n.X, getAddress) 295 296 case *ast.StarExpr: 297 x := e.evalNode(n.X, false) 298 switch v := x.v.(type) { 299 case debug.Pointer: 300 // x.d may be a typedef pointing to a pointer type (or a typedef pointing 301 // to a typedef pointing to a pointer type, etc.), so remove typedefs 302 // until we get the underlying pointer type. 303 t := followTypedefs(x.d) 304 if pt, ok := t.(*dwarf.PtrType); ok { 305 return e.resultFrom(v.Address, pt.Type, getAddress) 306 } else { 307 return e.err("invalid DWARF type for pointer") 308 } 309 case pointerToValue: 310 return e.resultFrom(v.a, x.d, getAddress) 311 case nil: 312 return x 313 } 314 return e.err("invalid indirect") 315 316 case *ast.SelectorExpr: 317 x := e.evalNode(n.X, false) 318 sel := n.Sel.Name 319 switch v := x.v.(type) { 320 case debug.Struct: 321 for _, f := range v.Fields { 322 if f.Name == sel { 323 t, err := e.server.dwarfData.Type(dwarf.Offset(f.Var.TypeID)) 324 if err != nil { 325 return e.err(err.Error()) 326 } 327 return e.resultFrom(f.Var.Address, t, getAddress) 328 } 329 } 330 return e.err("struct field not found") 331 case debug.Pointer: 332 pt, ok := followTypedefs(x.d).(*dwarf.PtrType) // x.d should be a pointer to struct. 333 if !ok { 334 return e.err("invalid DWARF information for pointer") 335 } 336 st, ok := followTypedefs(pt.Type).(*dwarf.StructType) 337 if !ok { 338 break 339 } 340 for _, f := range st.Field { 341 if f.Name == sel { 342 return e.resultFrom(v.Address+uint64(f.ByteOffset), f.Type, getAddress) 343 } 344 } 345 return e.err("struct field not found") 346 case pointerToValue: 347 st, ok := followTypedefs(x.d).(*dwarf.StructType) // x.d should be a struct. 348 if !ok { 349 break 350 } 351 for _, f := range st.Field { 352 if f.Name == sel { 353 return e.resultFrom(v.a+uint64(f.ByteOffset), f.Type, getAddress) 354 } 355 } 356 return e.err("struct field not found") 357 } 358 return e.err("invalid selector expression") 359 360 case *ast.IndexExpr: 361 x, index := e.evalNode(n.X, false), e.evalNode(n.Index, false) 362 if x.v == nil || index.v == nil { 363 return result{} 364 } 365 // The expression is x[index] 366 if m, ok := x.v.(debug.Map); ok { 367 if getAddress { 368 return e.err("can't take address of map value") 369 } 370 mt, ok := followTypedefs(x.d).(*dwarf.MapType) 371 if !ok { 372 return e.err("invalid DWARF type for map") 373 } 374 var ( 375 found bool // true if the key was found 376 value result // the map value for the key 377 abort bool // true if an error occurred while searching 378 // fn is a function that checks if one (key, value) pair corresponds 379 // to the index in the expression. 380 fn = func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool { 381 key := e.resultFrom(keyAddr, keyType, false) 382 if key.v == nil { 383 abort = true 384 return false // stop searching map 385 } 386 equal, ok := e.evalBinaryOp(token.EQL, index, key).v.(bool) 387 if !ok { 388 abort = true 389 return false // stop searching map 390 } 391 if equal { 392 found = true 393 value = e.resultFrom(valAddr, valType, false) 394 return false // stop searching map 395 } 396 return true // continue searching map 397 } 398 ) 399 if err := e.server.peekMapValues(mt, m.Address, fn); err != nil { 400 return e.err(err.Error()) 401 } 402 if abort { 403 // Some operation on individual map keys failed. 404 return result{} 405 } 406 if found { 407 return value 408 } 409 // The key wasn't in the map; return the zero value. 410 return e.zero(mt.ElemType) 411 } 412 413 // The index should be a non-negative integer for the remaining cases. 414 u, err := uint64FromResult(index) 415 if err != nil { 416 return e.err("invalid index: " + err.Error()) 417 } 418 switch v := x.v.(type) { 419 case debug.Array: 420 if u >= v.Length { 421 return e.err("array index out of bounds") 422 } 423 elemType, err := e.server.dwarfData.Type(dwarf.Offset(v.ElementTypeID)) 424 if err != nil { 425 return e.err(err.Error()) 426 } 427 return e.resultFrom(v.Element(u).Address, elemType, getAddress) 428 case debug.Slice: 429 if u >= v.Length { 430 return e.err("slice index out of bounds") 431 } 432 elemType, err := e.server.dwarfData.Type(dwarf.Offset(v.ElementTypeID)) 433 if err != nil { 434 return e.err(err.Error()) 435 } 436 return e.resultFrom(v.Element(u).Address, elemType, getAddress) 437 case sliceOf: 438 if u >= v.Length { 439 return e.err("slice index out of bounds") 440 } 441 return e.resultFrom(v.Element(u).Address, x.d, getAddress) 442 case debug.String: 443 if getAddress { 444 return e.err("can't take address of string element") 445 } 446 if u >= v.Length { 447 return e.err("string index out of bounds") 448 } 449 if u >= uint64(len(v.String)) { 450 return e.err("string element unavailable") 451 } 452 return e.uint8Result(v.String[u]) 453 case untString: 454 if getAddress { 455 return e.err("can't take address of string element") 456 } 457 if u >= uint64(len(v)) { 458 return e.err("string index out of bounds") 459 } 460 return e.uint8Result(v[u]) 461 } 462 return e.err("invalid index expression") 463 464 case *ast.SliceExpr: 465 if n.Slice3 && n.High == nil { 466 return e.err("middle index required in full slice") 467 } 468 if n.Slice3 && n.Max == nil { 469 return e.err("final index required in full slice") 470 } 471 var ( 472 low, high, max uint64 473 err error 474 ) 475 if n.Low != nil { 476 low, err = uint64FromResult(e.evalNode(n.Low, false)) 477 if err != nil { 478 return e.err("invalid slice lower bound: " + err.Error()) 479 } 480 } 481 if n.High != nil { 482 high, err = uint64FromResult(e.evalNode(n.High, false)) 483 if err != nil { 484 return e.err("invalid slice upper bound: " + err.Error()) 485 } 486 } 487 if n.Max != nil { 488 max, err = uint64FromResult(e.evalNode(n.Max, false)) 489 if err != nil { 490 return e.err("invalid slice capacity: " + err.Error()) 491 } 492 } 493 x := e.evalNode(n.X, false) 494 switch v := x.v.(type) { 495 case debug.Array, debug.Pointer, pointerToValue: 496 // This case handles the slicing of arrays and pointers to arrays. 497 var arr debug.Array 498 switch v := x.v.(type) { 499 case debug.Array: 500 arr = v 501 case debug.Pointer: 502 pt, ok := followTypedefs(x.d).(*dwarf.PtrType) 503 if !ok { 504 return e.err("invalid DWARF type for pointer") 505 } 506 a := e.resultFrom(v.Address, pt.Type, false) 507 arr, ok = a.v.(debug.Array) 508 if !ok { 509 // v is a pointer to something other than an array. 510 return e.err("cannot slice pointer") 511 } 512 case pointerToValue: 513 a := e.resultFrom(v.a, x.d, false) 514 var ok bool 515 arr, ok = a.v.(debug.Array) 516 if !ok { 517 // v is a pointer to something other than an array. 518 return e.err("cannot slice pointer") 519 } 520 } 521 elemType, err := e.server.dwarfData.Type(dwarf.Offset(arr.ElementTypeID)) 522 if err != nil { 523 return e.err(err.Error()) 524 } 525 if n.High == nil { 526 high = arr.Length 527 } else if high > arr.Length { 528 return e.err("slice upper bound is too large") 529 } 530 if n.Max == nil { 531 max = arr.Length 532 } else if max > arr.Length { 533 return e.err("slice capacity is too large") 534 } 535 if low > high || high > max { 536 return e.err("invalid slice index") 537 } 538 return result{ 539 d: elemType, 540 v: sliceOf{ 541 Array: debug.Array{ 542 ElementTypeID: arr.ElementTypeID, 543 Address: arr.Element(low).Address, 544 Length: high - low, 545 StrideBits: uint64(elemType.Common().ByteSize) * 8, 546 }, 547 Capacity: max - low, 548 }, 549 } 550 case debug.Slice: 551 if n.High == nil { 552 high = v.Length 553 } else if high > v.Capacity { 554 return e.err("slice upper bound is too large") 555 } 556 if n.Max == nil { 557 max = v.Capacity 558 } else if max > v.Capacity { 559 return e.err("slice capacity is too large") 560 } 561 if low > high || high > max { 562 return e.err("invalid slice index") 563 } 564 v.Address += low * (v.StrideBits / 8) 565 v.Length = high - low 566 v.Capacity = max - low 567 return result{x.d, v} 568 case sliceOf: 569 if n.High == nil { 570 high = v.Length 571 } else if high > v.Capacity { 572 return e.err("slice upper bound is too large") 573 } 574 if n.Max == nil { 575 max = v.Capacity 576 } else if max > v.Capacity { 577 return e.err("slice capacity is too large") 578 } 579 if low > high || high > max { 580 return e.err("invalid slice index") 581 } 582 v.Address += low * (v.StrideBits / 8) 583 v.Length = high - low 584 v.Capacity = max - low 585 return result{x.d, v} 586 case debug.String: 587 if n.Max != nil { 588 return e.err("full slice of string") 589 } 590 if n.High == nil { 591 high = v.Length 592 } 593 if low > high || high > v.Length { 594 return e.err("invalid slice index") 595 } 596 v.Length = high - low 597 if low > uint64(len(v.String)) { 598 // v.String was truncated before the point where this slice starts. 599 v.String = "" 600 } else { 601 if high > uint64(len(v.String)) { 602 // v.String was truncated before the point where this slice ends. 603 high = uint64(len(v.String)) 604 } 605 v.String = v.String[low:high] 606 } 607 return result{x.d, v} 608 case untString: 609 if n.Max != nil { 610 return e.err("full slice of string") 611 } 612 if n.High == nil { 613 high = uint64(len(v)) 614 } 615 if low > high { 616 return e.err("invalid slice expression") 617 } 618 if high > uint64(len(v)) { 619 return e.err("slice upper bound is too large") 620 } 621 return e.stringResult(string(v[low:high])) 622 default: 623 return e.err("invalid slice expression") 624 } 625 626 case *ast.CallExpr: 627 // Only supports lookup("x"), which gets the value of a global symbol x. 628 fun := e.evalNode(n.Fun, false) 629 var args []result 630 for _, a := range n.Args { 631 args = append(args, e.evalNode(a, false)) 632 } 633 if fun.v == identLookup { 634 if len(args) != 1 { 635 return e.err("lookup should have one argument") 636 } 637 ident, ok := args[0].v.(untString) 638 if !ok { 639 return e.err("argument for lookup should be a string constant") 640 } 641 if a, t := e.server.findGlobalVar(string(ident)); t == nil { 642 return e.err("symbol not found") 643 } else { 644 return e.resultFrom(a, t, getAddress) 645 } 646 } 647 return e.err("function calls not implemented") 648 649 case *ast.UnaryExpr: 650 if n.Op == token.AND { 651 x := e.evalNode(n.X, true) 652 switch v := x.v.(type) { 653 case addressableValue: 654 return result{x.d, pointerToValue{v.a}} 655 case nil: 656 return x 657 } 658 return e.err("can't take address") 659 } 660 661 x := e.evalNode(n.X, false) 662 if x.v == nil { 663 return x 664 } 665 switch v := x.v.(type) { 666m4_define(UNARY_INT_OPS, @case $1: 667 switch n.Op { 668 case token.ADD: 669 case token.SUB: 670 v = -v 671 case token.XOR: 672 v = ^v 673 default: 674 return e.err("invalid operation") 675 } 676 return result{x.d, v} 677@) 678m4_define(UNARY_FLOAT_OPS, @case $1: 679 switch n.Op { 680 case token.ADD: 681 case token.SUB: 682 v = -v 683 default: 684 return e.err("invalid operation") 685 } 686 return result{x.d, v} 687@) 688 UNARY_INT_OPS(int8) 689 UNARY_INT_OPS(int16) 690 UNARY_INT_OPS(int32) 691 UNARY_INT_OPS(int64) 692 UNARY_INT_OPS(uint8) 693 UNARY_INT_OPS(uint16) 694 UNARY_INT_OPS(uint32) 695 UNARY_INT_OPS(uint64) 696 UNARY_FLOAT_OPS(float32) 697 UNARY_FLOAT_OPS(float64) 698 UNARY_FLOAT_OPS(complex64) 699 UNARY_FLOAT_OPS(complex128) 700 case untInt: 701 switch n.Op { 702 case token.ADD: 703 case token.SUB: 704 v.Int.Neg(v.Int) 705 case token.XOR: 706 v.Int.Not(v.Int) 707 default: 708 return e.err("invalid operation") 709 } 710 return result{x.d, v} 711 712 case untRune: 713 switch n.Op { 714 case token.ADD: 715 case token.SUB: 716 v.Int.Neg(v.Int) 717 case token.XOR: 718 v.Int.Not(v.Int) 719 default: 720 return e.err("invalid operation") 721 } 722 return result{x.d, v} 723 724 case untFloat: 725 switch n.Op { 726 case token.ADD: 727 case token.SUB: 728 v.Float.Neg(v.Float) 729 default: 730 return e.err("invalid operation") 731 } 732 return result{x.d, v} 733 734 case untComplex: 735 switch n.Op { 736 case token.ADD: 737 case token.SUB: 738 v.r.Neg(v.r) 739 v.i.Neg(v.i) 740 default: 741 return e.err("invalid operation") 742 } 743 return result{x.d, v} 744 745 case bool: 746 switch n.Op { 747 case token.NOT: 748 v = !v 749 default: 750 return e.err("invalid operation") 751 } 752 return result{x.d, v} 753 } 754 755 case *ast.BinaryExpr: 756 x := e.evalNode(n.X, false) 757 if x.v == nil { 758 return x 759 } 760 y := e.evalNode(n.Y, false) 761 if y.v == nil { 762 return y 763 } 764 return e.evalBinaryOp(n.Op, x, y) 765 } 766 return e.err("invalid expression") 767} 768 769// evalBinaryOp evaluates a binary operator op applied to x and y. 770func (e *evaluator) evalBinaryOp(op token.Token, x, y result) result { 771 if op == token.NEQ { 772 tmp := e.evalBinaryOp(token.EQL, x, y) 773 b, ok := tmp.v.(bool) 774 if !ok { 775 return tmp 776 } 777 return result{nil, !b} 778 } 779 if op == token.GTR { 780 return e.evalBinaryOp(token.LSS, y, x) 781 } 782 if op == token.GEQ { 783 return e.evalBinaryOp(token.LEQ, x, y) 784 } 785 786 x = convertUntyped(x, y) 787 y = convertUntyped(y, x) 788 789 switch a := x.v.(type) { 790m4_define(INT_OPS, @case $1: 791 b, ok := y.v.($1) 792 if !ok { 793 return e.err("type mismatch") 794 } 795 var c $1 796 switch op { 797 case token.EQL: 798 return result{nil, a == b} 799 case token.LSS: 800 return result{nil, a < b} 801 case token.LEQ: 802 return result{nil, a <= b} 803 case token.ADD: 804 c = a + b 805 case token.SUB: 806 c = a - b 807 case token.OR: 808 c = a | b 809 case token.XOR: 810 c = a ^ b 811 case token.MUL: 812 c = a * b 813 case token.QUO: 814 if b == 0 { 815 return e.err("integer divide by zero") 816 } 817 c = a / b 818 case token.REM: 819 if b == 0 { 820 return e.err("integer divide by zero") 821 } 822 c = a % b 823 case token.AND: 824 c = a & b 825 case token.AND_NOT: 826 c = a &^ b 827 default: 828 return e.err("invalid operation") 829 } 830 return result{x.d, c} 831@) 832m4_define(UINT_OPS, @case $1: 833 b, ok := y.v.($1) 834 if !ok { 835 return e.err("type mismatch") 836 } 837 var c $1 838 switch op { 839 case token.EQL: 840 return result{nil, a == b} 841 case token.LSS: 842 return result{nil, a < b} 843 case token.LEQ: 844 return result{nil, a <= b} 845 case token.ADD: 846 c = a + b 847 case token.SUB: 848 c = a - b 849 case token.OR: 850 c = a | b 851 case token.XOR: 852 c = a ^ b 853 case token.MUL: 854 c = a * b 855 case token.QUO: 856 if b == 0 { 857 return e.err("integer divide by zero") 858 } 859 c = a / b 860 case token.REM: 861 if b == 0 { 862 return e.err("integer divide by zero") 863 } 864 c = a % b 865 case token.AND: 866 c = a & b 867 case token.AND_NOT: 868 c = a &^ b 869 default: 870 return e.err("invalid operation") 871 } 872 return result{x.d, c} 873@) 874m4_define(FLOAT_OPS, @case $1: 875 b, ok := y.v.($1) 876 if !ok { 877 return e.err("type mismatch") 878 } 879 var c $1 880 switch op { 881 case token.EQL: 882 return result{nil, a == b} 883 case token.LSS: 884 return result{nil, a < b} 885 case token.LEQ: 886 return result{nil, a <= b} 887 case token.ADD: 888 c = a + b 889 case token.SUB: 890 c = a - b 891 case token.MUL: 892 c = a * b 893 case token.QUO: 894 c = a / b 895 default: 896 return e.err("invalid operation") 897 } 898 return result{x.d, c} 899@) 900m4_define(COMPLEX_OPS, @case $1: 901 b, ok := y.v.($1) 902 if !ok { 903 return e.err("type mismatch") 904 } 905 var c $1 906 switch op { 907 case token.EQL: 908 return result{nil, a == b} 909 case token.ADD: 910 c = a + b 911 case token.SUB: 912 c = a - b 913 case token.MUL: 914 c = a * b 915 case token.QUO: 916 c = a / b 917 default: 918 return e.err("invalid operation") 919 } 920 return result{x.d, c} 921@) 922 INT_OPS(int8) 923 INT_OPS(int16) 924 INT_OPS(int32) 925 INT_OPS(int64) 926 UINT_OPS(uint8) 927 UINT_OPS(uint16) 928 UINT_OPS(uint32) 929 UINT_OPS(uint64) 930 FLOAT_OPS(float32) 931 FLOAT_OPS(float64) 932 COMPLEX_OPS(complex64) 933 COMPLEX_OPS(complex128) 934 case bool: 935 b, ok := y.v.(bool) 936 if !ok { 937 return e.err("type mismatch") 938 } 939 var c bool 940 switch op { 941 case token.LOR: 942 c = a || b 943 case token.LAND: 944 c = a && b 945 case token.EQL: 946 c = a == b 947 default: 948 return e.err("invalid operation") 949 } 950 return result{x.d, c} 951 952 case debug.String: 953 b, ok := y.v.(debug.String) 954 if !ok { 955 return e.err("type mismatch") 956 } 957 var c debug.String 958 switch op { 959 // TODO: these comparison operators only use the part of the string that 960 // was read. Very large strings do not have their entire contents read by 961 // server.value. 962 case token.EQL: 963 return result{nil, a.Length == b.Length && a.String == b.String} 964 case token.LSS: 965 return result{nil, a.String < b.String} 966 case token.LEQ: 967 return result{nil, a.String <= b.String} 968 case token.ADD: 969 c.Length = a.Length + b.Length 970 if a.Length == uint64(len(a.String)) { 971 c.String = a.String + b.String 972 } else { 973 // The first string was truncated at a.Length characters, so the sum 974 // must be truncated there too. 975 c.String = a.String 976 } 977 default: 978 return e.err("invalid operation") 979 } 980 return result{x.d, c} 981 982 case untString: 983 b, ok := y.v.(untString) 984 if !ok { 985 return e.err("type mismatch") 986 } 987 var c untString 988 switch op { 989 case token.EQL: 990 return result{nil, a == b} 991 case token.LSS: 992 return result{nil, a < b} 993 case token.LEQ: 994 return result{nil, a <= b} 995 case token.ADD: 996 c = a + b 997 default: 998 return e.err("invalid operation") 999 } 1000 return result{x.d, c} 1001 1002 case untInt: 1003 i := a.Int 1004 b, ok := y.v.(untInt) 1005 if !ok { 1006 return e.err("type mismatch") 1007 } 1008 switch op { 1009 case token.EQL: 1010 return result{nil, i.Cmp(b.Int) == 0} 1011 case token.LSS: 1012 return result{nil, i.Cmp(b.Int) < 0} 1013 case token.LEQ: 1014 return result{nil, i.Cmp(b.Int) <= 0} 1015 } 1016 c := new(big.Int) 1017 switch op { 1018 case token.ADD: 1019 c.Add(i, b.Int) 1020 case token.SUB: 1021 c.Sub(i, b.Int) 1022 case token.OR: 1023 c.Or(i, b.Int) 1024 case token.XOR: 1025 c.Xor(i, b.Int) 1026 case token.MUL: 1027 c.Mul(i, b.Int) 1028 case token.QUO: 1029 if b.Sign() == 0 { 1030 return e.err("integer divide by zero") 1031 } 1032 c.Quo(i, b.Int) 1033 case token.REM: 1034 if b.Sign() == 0 { 1035 return e.err("integer divide by zero") 1036 } 1037 c.Mod(i, b.Int) 1038 case token.AND: 1039 c.And(i, b.Int) 1040 case token.AND_NOT: 1041 c.AndNot(i, b.Int) 1042 default: 1043 return e.err("invalid operation") 1044 } 1045 return result{nil, untInt{c}} 1046 1047 case untRune: 1048 i := a.Int 1049 b, ok := y.v.(untRune) 1050 if !ok { 1051 return e.err("type mismatch") 1052 } 1053 switch op { 1054 case token.EQL: 1055 return result{nil, i.Cmp(b.Int) == 0} 1056 case token.LSS: 1057 return result{nil, i.Cmp(b.Int) < 0} 1058 case token.LEQ: 1059 return result{nil, i.Cmp(b.Int) <= 0} 1060 } 1061 c := new(big.Int) 1062 switch op { 1063 case token.ADD: 1064 c.Add(i, b.Int) 1065 case token.SUB: 1066 c.Sub(i, b.Int) 1067 case token.OR: 1068 c.Or(i, b.Int) 1069 case token.XOR: 1070 c.Xor(i, b.Int) 1071 case token.MUL: 1072 c.Mul(i, b.Int) 1073 case token.QUO: 1074 if b.Sign() == 0 { 1075 return e.err("integer divide by zero") 1076 } 1077 c.Quo(i, b.Int) 1078 case token.REM: 1079 if b.Sign() == 0 { 1080 return e.err("integer divide by zero") 1081 } 1082 c.Mod(i, b.Int) 1083 case token.AND: 1084 c.And(i, b.Int) 1085 case token.AND_NOT: 1086 c.AndNot(i, b.Int) 1087 default: 1088 return e.err("invalid operation") 1089 } 1090 return result{nil, untRune{c}} 1091 1092 case untFloat: 1093 r := a.Float 1094 b, ok := y.v.(untFloat) 1095 if !ok { 1096 return e.err("type mismatch") 1097 } 1098 switch op { 1099 case token.EQL: 1100 return result{nil, r.Cmp(b.Float) == 0} 1101 case token.LSS: 1102 return result{nil, r.Cmp(b.Float) < 0} 1103 case token.LEQ: 1104 return result{nil, r.Cmp(b.Float) <= 0} 1105 } 1106 c := new(big.Float) 1107 switch op { 1108 case token.ADD: 1109 c.Add(r, b.Float) 1110 case token.SUB: 1111 c.Sub(r, b.Float) 1112 case token.MUL: 1113 c.Mul(r, b.Float) 1114 case token.QUO: 1115 if b.Sign() == 0 { 1116 return e.err("divide by zero") 1117 } 1118 c.Quo(r, b.Float) 1119 default: 1120 return e.err("invalid operation") 1121 } 1122 return result{nil, untFloat{c}} 1123 1124 case untComplex: 1125 b, ok := y.v.(untComplex) 1126 if !ok { 1127 return e.err("type mismatch") 1128 } 1129 var ( 1130 ar = a.r 1131 br = b.r 1132 ai = a.i 1133 bi = b.i 1134 ) 1135 if op == token.EQL { 1136 return result{nil, ar.Cmp(br) == 0 && ai.Cmp(bi) == 0} 1137 } 1138 var ( 1139 cr = new(big.Float) 1140 ci = new(big.Float) 1141 ) 1142 switch op { 1143 case token.ADD: 1144 cr.Add(ar, br) 1145 ci.Add(ai, bi) 1146 case token.SUB: 1147 cr.Sub(ar, br) 1148 ci.Sub(ai, bi) 1149 case token.MUL: 1150 var t0, t1 big.Float 1151 t0.Mul(ar, br) 1152 t1.Mul(ai, bi) 1153 cr.Sub(&t0, &t1) 1154 t0.Mul(ar, bi) 1155 t1.Mul(ai, br) 1156 ci.Add(&t0, &t1) 1157 case token.QUO: 1158 // a/b = a*conj(b)/|b|^2 1159 var t0, t1 big.Float 1160 cr.Mul(ar, br) 1161 t0.Mul(ai, bi) 1162 cr.Add(cr, &t0) // cr = Re(a*conj(b)) 1163 ci.Mul(ai, br) 1164 t0.Mul(ar, bi) 1165 ci.Sub(ci, &t0) // ci = Im(a*conj(b)) 1166 t0.Mul(br, br) 1167 t1.Mul(bi, bi) 1168 t0.Add(&t0, &t1) // t0 = |b|^2 1169 if t0.Sign() == 0 { 1170 return e.err("divide by zero") 1171 } 1172 cr.Quo(cr, &t0) // cr = Re(a*conj(b))/|b|^2 = Re(a/b) 1173 ci.Quo(ci, &t0) // ci = Im(a*conj(b))/|b|^2 = Im(a/b) 1174 } 1175 return result{nil, untComplex{cr, ci}} 1176 } 1177 1178 return e.err("invalid operation") 1179} 1180 1181// findLocalVar finds a local variable (or function parameter) by name, and 1182// returns its address and DWARF type. It returns a nil type on failure. 1183// The PC and SP are used to determine the current function and stack frame. 1184func (s *Server) findLocalVar(name string, pc, sp uint64) (uint64, dwarf.Type) { 1185 // Find the DWARF entry for the function at pc. 1186 funcEntry, _, err := s.dwarfData.PCToFunction(uint64(pc)) 1187 if err != nil { 1188 return 0, nil 1189 } 1190 1191 // Compute the stack frame pointer. 1192 fpOffset, err := s.dwarfData.PCToSPOffset(uint64(pc)) 1193 if err != nil { 1194 return 0, nil 1195 } 1196 framePointer := sp + uint64(fpOffset) 1197 1198 // Check each child of the function's DWARF entry to see if it is a parameter 1199 // or local variable with the right name. If so, return its address and type. 1200 r := s.dwarfData.Reader() 1201 r.Seek(funcEntry.Offset) 1202 for { 1203 varEntry, err := r.Next() 1204 if err != nil { 1205 break 1206 } 1207 if varEntry.Tag == 0 { 1208 // This tag marks the end of the function's DWARF entry's children. 1209 break 1210 } 1211 1212 // Check this entry corresponds to a local variable or function parameter, 1213 // that it has the correct name, and that we can get its type and location. 1214 // If so, return them. 1215 if varEntry.Tag != dwarf.TagFormalParameter && varEntry.Tag != dwarf.TagVariable { 1216 continue 1217 } 1218 varName, ok := varEntry.Val(dwarf.AttrName).(string) 1219 if !ok { 1220 continue 1221 } 1222 if varName != name { 1223 continue 1224 } 1225 varTypeOffset, ok := varEntry.Val(dwarf.AttrType).(dwarf.Offset) 1226 if !ok { 1227 continue 1228 } 1229 varType, err := s.dwarfData.Type(varTypeOffset) 1230 if err != nil { 1231 continue 1232 } 1233 locationAttribute := varEntry.Val(dwarf.AttrLocation) 1234 if locationAttribute == nil { 1235 continue 1236 } 1237 locationDescription, ok := locationAttribute.([]uint8) 1238 if !ok { 1239 continue 1240 } 1241 frameOffset, err := evalLocation(locationDescription) 1242 if err != nil { 1243 continue 1244 } 1245 return framePointer + uint64(frameOffset), varType 1246 } 1247 1248 return 0, nil 1249} 1250 1251// findGlobalVar finds a global variable by name, and returns its address and 1252// DWARF type. It returns a nil type on failure. 1253func (s *Server) findGlobalVar(name string) (uint64, dwarf.Type) { 1254 entry, err := s.dwarfData.LookupVariable(name) 1255 if err != nil { 1256 return 0, nil 1257 } 1258 loc, err := s.dwarfData.EntryLocation(entry) 1259 if err != nil { 1260 return 0, nil 1261 } 1262 ofs, err := s.dwarfData.EntryTypeOffset(entry) 1263 if err != nil { 1264 return 0, nil 1265 } 1266 typ, err := s.dwarfData.Type(ofs) 1267 if err != nil { 1268 return 0, nil 1269 } 1270 return loc, typ 1271} 1272 1273// intFromInteger converts an untyped integer constant to an int32 or int64, 1274// depending on the int size of the debugged program. 1275// It returns an error on overflow, or if it can't determine the int size. 1276func (e *evaluator) intFromInteger(v untInt) (interface{}, error) { 1277 t, ok := e.getBaseType("int") 1278 if !ok { 1279 return nil, errors.New("couldn't get int size from DWARF info") 1280 } 1281 switch t.Common().ByteSize { 1282 case 4: 1283 if v.Cmp(bigIntMaxInt32) == +1 || v.Cmp(bigIntMinInt32) == -1 { 1284 return nil, errors.New("constant overflows int") 1285 } 1286 return int32(v.Int64()), nil 1287 case 8: 1288 if v.Cmp(bigIntMaxInt64) == +1 || v.Cmp(bigIntMinInt64) == -1 { 1289 return nil, errors.New("constant overflows int") 1290 } 1291 return v.Int64(), nil 1292 } 1293 return nil, errors.New("invalid int size in DWARF info") 1294} 1295 1296// uint8Result constructs a result for a uint8 value. 1297func (e *evaluator) uint8Result(v uint8) result { 1298 t, ok := e.getBaseType("uint8") 1299 if !ok { 1300 e.err("couldn't construct uint8") 1301 } 1302 return result{t, uint8(v)} 1303} 1304 1305// stringResult constructs a result for a string value. 1306func (e *evaluator) stringResult(s string) result { 1307 t, ok := e.getBaseType("string") 1308 if !ok { 1309 e.err("couldn't construct string") 1310 } 1311 return result{t, debug.String{Length: uint64(len(s)), String: s}} 1312} 1313 1314// getBaseType returns the *dwarf.Type with a given name. 1315// TODO: cache this. 1316func (e *evaluator) getBaseType(name string) (dwarf.Type, bool) { 1317 entry, err := e.server.dwarfData.LookupEntry(name) 1318 if err != nil { 1319 return nil, false 1320 } 1321 t, err := e.server.dwarfData.Type(entry.Offset) 1322 if err != nil { 1323 return nil, false 1324 } 1325 return t, true 1326} 1327 1328// resultFrom constructs a result corresponding to a value in the program with 1329// the given address and DWARF type. 1330// If getAddress is true, the result will be the operand of an address expression, 1331// so resultFrom returns a result containing a value of type addressableValue. 1332func (e *evaluator) resultFrom(a uint64, t dwarf.Type, getAddress bool) result { 1333 if a == 0 { 1334 return e.err("nil pointer dereference") 1335 } 1336 if getAddress { 1337 return result{t, addressableValue{a}} 1338 } 1339 v, err := e.server.value(t, a) 1340 if err != nil { 1341 return e.err(err.Error()) 1342 } 1343 return result{t, v} 1344} 1345 1346// zero returns the zero value of type t. 1347// TODO: implement for array and struct. 1348func (e *evaluator) zero(t dwarf.Type) result { 1349 var v interface{} 1350 switch typ := followTypedefs(t).(type) { 1351 case *dwarf.CharType, *dwarf.IntType, *dwarf.EnumType: 1352 switch typ.Common().ByteSize { 1353 case 1: 1354 v = int8(0) 1355 case 2: 1356 v = int16(0) 1357 case 4: 1358 v = int32(0) 1359 case 8: 1360 v = int64(0) 1361 default: 1362 return e.err("invalid integer size " + fmt.Sprint(typ.Common().ByteSize)) 1363 } 1364 case *dwarf.UcharType, *dwarf.UintType: 1365 switch typ.Common().ByteSize { 1366 case 1: 1367 v = uint8(0) 1368 case 2: 1369 v = uint16(0) 1370 case 4: 1371 v = uint32(0) 1372 case 8: 1373 v = uint64(0) 1374 default: 1375 return e.err("invalid unsigned integer size " + fmt.Sprint(typ.Common().ByteSize)) 1376 } 1377 case *dwarf.FloatType: 1378 switch typ.Common().ByteSize { 1379 case 4: 1380 v = float32(0) 1381 case 8: 1382 v = float64(0) 1383 default: 1384 return e.err("invalid float size " + fmt.Sprint(typ.Common().ByteSize)) 1385 } 1386 case *dwarf.ComplexType: 1387 switch typ.Common().ByteSize { 1388 case 8: 1389 v = complex64(0) 1390 case 16: 1391 v = complex128(0) 1392 default: 1393 return e.err("invalid complex size " + fmt.Sprint(typ.Common().ByteSize)) 1394 } 1395 case *dwarf.BoolType: 1396 v = false 1397 case *dwarf.PtrType: 1398 v = debug.Pointer{TypeID: uint64(t.Common().Offset)} 1399 case *dwarf.SliceType: 1400 v = debug.Slice{ 1401 Array: debug.Array{ 1402 ElementTypeID: uint64(typ.ElemType.Common().Offset), 1403 StrideBits: uint64(typ.ElemType.Common().ByteSize) * 8, 1404 }, 1405 } 1406 case *dwarf.StringType: 1407 v = debug.String{} 1408 case *dwarf.InterfaceType: 1409 v = debug.Interface{} 1410 case *dwarf.FuncType: 1411 v = debug.Func{} 1412 case *dwarf.MapType: 1413 v = debug.Map{TypeID: uint64(t.Common().Offset)} 1414 case *dwarf.ChanType: 1415 v = debug.Channel{ 1416 ElementTypeID: uint64(typ.ElemType.Common().Offset), 1417 Stride: uint64(typ.ElemType.Common().ByteSize), 1418 } 1419 default: 1420 return e.err("can't get zero value of this type") 1421 } 1422 return result{t, v} 1423} 1424 1425// convertUntyped converts x to be the same type as y, if x is untyped and the 1426// conversion is possible. 1427// 1428// An untyped bool can be converted to a boolean type. 1429// An untyped string can be converted to a string type. 1430// An untyped integer, rune, float or complex value can be converted to a 1431// numeric type, or to an untyped value later in that list. 1432// 1433// x is returned unchanged if none of these cases apply. 1434func convertUntyped(x, y result) result { 1435 switch a := x.v.(type) { 1436 case untInt: 1437 i := a.Int 1438 switch y.v.(type) { 1439 case int8: 1440 return result{y.d, int8(i.Int64())} 1441 case int16: 1442 return result{y.d, int16(i.Int64())} 1443 case int32: 1444 return result{y.d, int32(i.Int64())} 1445 case int64: 1446 return result{y.d, int64(i.Int64())} 1447 case uint8: 1448 return result{y.d, uint8(i.Uint64())} 1449 case uint16: 1450 return result{y.d, uint16(i.Uint64())} 1451 case uint32: 1452 return result{y.d, uint32(i.Uint64())} 1453 case uint64: 1454 return result{y.d, uint64(i.Uint64())} 1455 case float32: 1456 f, _ := new(big.Float).SetInt(i).Float32() 1457 return result{y.d, f} 1458 case float64: 1459 f, _ := new(big.Float).SetInt(i).Float64() 1460 return result{y.d, f} 1461 case complex64: 1462 f, _ := new(big.Float).SetInt(i).Float32() 1463 return result{y.d, complex(f, 0)} 1464 case complex128: 1465 f, _ := new(big.Float).SetInt(i).Float64() 1466 return result{y.d, complex(f, 0)} 1467 case untRune: 1468 return result{nil, untRune{i}} 1469 case untFloat: 1470 return result{nil, untFloat{new(big.Float).SetPrec(prec).SetInt(i)}} 1471 case untComplex: 1472 return result{nil, untComplex{new(big.Float).SetPrec(prec).SetInt(i), new(big.Float)}} 1473 } 1474 case untRune: 1475 i := a.Int 1476 switch y.v.(type) { 1477 case int8: 1478 return result{y.d, int8(i.Int64())} 1479 case int16: 1480 return result{y.d, int16(i.Int64())} 1481 case int32: 1482 return result{y.d, int32(i.Int64())} 1483 case int64: 1484 return result{y.d, int64(i.Int64())} 1485 case uint8: 1486 return result{y.d, uint8(i.Uint64())} 1487 case uint16: 1488 return result{y.d, uint16(i.Uint64())} 1489 case uint32: 1490 return result{y.d, uint32(i.Uint64())} 1491 case uint64: 1492 return result{y.d, uint64(i.Uint64())} 1493 case float32: 1494 f, _ := new(big.Float).SetInt(i).Float32() 1495 return result{y.d, f} 1496 case float64: 1497 f, _ := new(big.Float).SetInt(i).Float64() 1498 return result{y.d, f} 1499 case complex64: 1500 f, _ := new(big.Float).SetInt(i).Float32() 1501 return result{y.d, complex(f, 0)} 1502 case complex128: 1503 f, _ := new(big.Float).SetInt(i).Float64() 1504 return result{y.d, complex(f, 0)} 1505 case untRune: 1506 return result{nil, untRune{i}} 1507 case untFloat: 1508 return result{nil, untFloat{new(big.Float).SetPrec(prec).SetInt(i)}} 1509 case untComplex: 1510 return result{nil, untComplex{new(big.Float).SetPrec(prec).SetInt(i), new(big.Float)}} 1511 } 1512 case untFloat: 1513 if a.IsInt() { 1514 i, _ := a.Int(nil) 1515 switch y.v.(type) { 1516 case int8: 1517 return result{y.d, int8(i.Int64())} 1518 case int16: 1519 return result{y.d, int16(i.Int64())} 1520 case int32: 1521 return result{y.d, int32(i.Int64())} 1522 case int64: 1523 return result{y.d, int64(i.Int64())} 1524 case uint8: 1525 return result{y.d, uint8(i.Uint64())} 1526 case uint16: 1527 return result{y.d, uint16(i.Uint64())} 1528 case uint32: 1529 return result{y.d, uint32(i.Uint64())} 1530 case uint64: 1531 return result{y.d, uint64(i.Uint64())} 1532 } 1533 } 1534 switch y.v.(type) { 1535 case float32: 1536 f, _ := a.Float32() 1537 return result{y.d, float32(f)} 1538 case float64: 1539 f, _ := a.Float64() 1540 return result{y.d, float64(f)} 1541 case complex64: 1542 f, _ := a.Float32() 1543 return result{y.d, complex(f, 0)} 1544 case complex128: 1545 f, _ := a.Float64() 1546 return result{y.d, complex(f, 0)} 1547 case untComplex: 1548 return result{nil, untComplex{a.Float, new(big.Float)}} 1549 } 1550 case untComplex: 1551 if a.i.Sign() == 0 { 1552 // a is a real number. 1553 if a.r.IsInt() { 1554 // a is an integer. 1555 i, _ := a.r.Int(nil) 1556 switch y.v.(type) { 1557 case int8: 1558 return result{y.d, int8(i.Int64())} 1559 case int16: 1560 return result{y.d, int16(i.Int64())} 1561 case int32: 1562 return result{y.d, int32(i.Int64())} 1563 case int64: 1564 return result{y.d, int64(i.Int64())} 1565 case uint8: 1566 return result{y.d, uint8(i.Uint64())} 1567 case uint16: 1568 return result{y.d, uint16(i.Uint64())} 1569 case uint32: 1570 return result{y.d, uint32(i.Uint64())} 1571 case uint64: 1572 return result{y.d, uint64(i.Uint64())} 1573 } 1574 } 1575 switch y.v.(type) { 1576 case float32: 1577 f, _ := a.r.Float32() 1578 return result{y.d, float32(f)} 1579 case float64: 1580 f, _ := a.r.Float64() 1581 return result{y.d, float64(f)} 1582 } 1583 } 1584 switch y.v.(type) { 1585 case complex64: 1586 r, _ := a.r.Float32() 1587 i, _ := a.i.Float32() 1588 return result{y.d, complex(r, i)} 1589 case complex128: 1590 r, _ := a.r.Float64() 1591 i, _ := a.i.Float64() 1592 return result{y.d, complex(r, i)} 1593 } 1594 case bool: 1595 if x.d != nil { 1596 // x is a typed bool, not an untyped bool. 1597 break 1598 } 1599 switch y.v.(type) { 1600 case bool: 1601 return result{y.d, bool(a)} 1602 } 1603 case untString: 1604 switch y.v.(type) { 1605 case debug.String: 1606 return result{y.d, debug.String{Length: uint64(len(a)), String: string(a)}} 1607 } 1608 } 1609 return x 1610} 1611 1612// uint64FromResult converts a result into a uint64 for slice or index expressions. 1613// It returns an error if the conversion cannot be done. 1614func uint64FromResult(x result) (uint64, error) { 1615 switch v := x.v.(type) { 1616 case int8: 1617 if v < 0 { 1618 return 0, errors.New("value is negative") 1619 } 1620 return uint64(v), nil 1621 case int16: 1622 if v < 0 { 1623 return 0, errors.New("value is negative") 1624 } 1625 return uint64(v), nil 1626 case int32: 1627 if v < 0 { 1628 return 0, errors.New("value is negative") 1629 } 1630 return uint64(v), nil 1631 case int64: 1632 if v < 0 { 1633 return 0, errors.New("value is negative") 1634 } 1635 return uint64(v), nil 1636 case uint8: 1637 return uint64(v), nil 1638 case uint16: 1639 return uint64(v), nil 1640 case uint32: 1641 return uint64(v), nil 1642 case uint64: 1643 return v, nil 1644 case untInt: 1645 if v.Int.Sign() == -1 { 1646 return 0, errors.New("value is negative") 1647 } 1648 if v.Int.Cmp(bigIntMaxUint64) == +1 { 1649 return 0, errors.New("value is too large") 1650 } 1651 return v.Int.Uint64(), nil 1652 case untRune: 1653 if v.Sign() == -1 { 1654 return 0, errors.New("value is negative") 1655 } 1656 if v.Cmp(bigIntMaxUint64) == +1 { 1657 return 0, errors.New("value is too large") 1658 } 1659 return v.Uint64(), nil 1660 case untFloat: 1661 if !v.IsInt() { 1662 return 0, errors.New("value is not an integer") 1663 } 1664 if v.Sign() == -1 { 1665 return 0, errors.New("value is negative") 1666 } 1667 i, _ := v.Int(nil) 1668 if i.Cmp(bigIntMaxUint64) == +1 { 1669 return 0, errors.New("value is too large") 1670 } 1671 return i.Uint64(), nil 1672 case untComplex: 1673 if v.i.Sign() != 0 { 1674 return 0, errors.New("value is complex") 1675 } 1676 if !v.r.IsInt() { 1677 return 0, errors.New("value is not an integer") 1678 } 1679 if v.r.Sign() == -1 { 1680 return 0, errors.New("value is negative") 1681 } 1682 i, _ := v.r.Int(nil) 1683 if i.Cmp(bigIntMaxUint64) == +1 { 1684 return 0, errors.New("value is too large") 1685 } 1686 return i.Uint64(), nil 1687 } 1688 return 0, fmt.Errorf("cannot convert to unsigned integer") 1689} 1690 1691// followTypedefs returns the underlying type of t, removing any typedefs. 1692// If t leads to a cycle of typedefs, followTypedefs returns nil. 1693func followTypedefs(t dwarf.Type) dwarf.Type { 1694 // If t is a *dwarf.TypedefType, next returns t.Type, otherwise it returns t. 1695 // The bool returned is true when the argument was a typedef. 1696 next := func(t dwarf.Type) (dwarf.Type, bool) { 1697 tt, ok := t.(*dwarf.TypedefType) 1698 if !ok { 1699 return t, false 1700 } 1701 return tt.Type, true 1702 } 1703 // Advance two pointers, one at twice the speed, so we can detect if we get 1704 // stuck in a cycle. 1705 slow, fast := t, t 1706 for { 1707 var wasTypedef bool 1708 fast, wasTypedef = next(fast) 1709 if !wasTypedef { 1710 return fast 1711 } 1712 fast, wasTypedef = next(fast) 1713 if !wasTypedef { 1714 return fast 1715 } 1716 slow, _ = next(slow) 1717 if slow == fast { 1718 return nil 1719 } 1720 } 1721} 1722