func prettyTypeName(typ dwarf.Type) string { if typ == nil { return "" } r := typ.String() if r == "*void" { return "unsafe.Pointer" } return r }
// sizeof returns the byte size of the type. func (p *Printer) sizeof(typ dwarf.Type) (uint64, bool) { size := typ.Size() // Will be -1 if ByteSize is not set. if size >= 0 { return uint64(size), true } switch typ.(type) { case *dwarf.PtrType: // This is the only one we know of, but more may arise. return uint64(p.arch.PointerSize), true } return 0, false }
func (v *Variable) isType(typ dwarf.Type, kind reflect.Kind) error { if v.DwarfType != nil { if typ != nil && typ.String() != v.RealType.String() { return fmt.Errorf("can not convert value of type %s to %s", v.DwarfType.String(), typ.String()) } return nil } if typ == nil { return nil } if v == nilVariable { switch kind { case reflect.Slice, reflect.Map, reflect.Func, reflect.Ptr, reflect.Chan, reflect.Interface: return nil default: return fmt.Errorf("mismatched types nil and %s", typ.String()) } } converr := fmt.Errorf("can not convert %s constant to %s", v.Value, typ.String()) if v.Value == nil { return converr } switch typ.(type) { case *dwarf.IntType: if v.Value.Kind() != constant.Int { return converr } case *dwarf.UintType: if v.Value.Kind() != constant.Int { return converr } case *dwarf.FloatType: if (v.Value.Kind() != constant.Int) && (v.Value.Kind() != constant.Float) { return converr } case *dwarf.BoolType: if v.Value.Kind() != constant.Bool { return converr } case *dwarf.StringType: if v.Value.Kind() != constant.String { return converr } case *dwarf.ComplexType: if v.Value.Kind() != constant.Complex && v.Value.Kind() != constant.Float && v.Value.Kind() != constant.Int { return converr } default: return converr } return nil }
// printValueAt pretty-prints the data at the specified address. // using the provided type information. func (p *Printer) printValueAt(typ dwarf.Type, a uint64) { if a != 0 { // Check if we are repeating the same type and address. ta := typeAndAddress{typ, a} if p.visited[ta] { p.printf("(%v %#x)", typ, a) return } p.visited[ta] = true } switch typ := typ.(type) { case *dwarf.BoolType: if typ.ByteSize != 1 { p.errorf("unrecognized bool size %d", typ.ByteSize) return } if b, err := p.server.peekUint8(a); err != nil { p.errorf("reading bool: %s", err) } else { p.printf("%t", b != 0) } case *dwarf.PtrType: if ptr, err := p.server.peekPtr(a); err != nil { p.errorf("reading pointer: %s", err) } else { p.printf("%#x", ptr) } case *dwarf.IntType: // Sad we can't tell a rune from an int32. if i, err := p.server.peekInt(a, typ.ByteSize); err != nil { p.errorf("reading integer: %s", err) } else { p.printf("%d", i) } case *dwarf.UintType: if u, err := p.server.peekUint(a, typ.ByteSize); err != nil { p.errorf("reading unsigned integer: %s", err) } else { p.printf("%d", u) } case *dwarf.FloatType: buf := make([]byte, typ.ByteSize) if err := p.server.peekBytes(a, buf); err != nil { p.errorf("reading float: %s", err) return } switch typ.ByteSize { case 4: p.printf("%g", p.arch.Float32(buf)) case 8: p.printf("%g", p.arch.Float64(buf)) default: p.errorf("unrecognized float size %d", typ.ByteSize) } case *dwarf.ComplexType: buf := make([]byte, typ.ByteSize) if err := p.server.peekBytes(a, buf); err != nil { p.errorf("reading complex: %s", err) return } switch typ.ByteSize { case 8: p.printf("%g", p.arch.Complex64(buf)) case 16: p.printf("%g", p.arch.Complex128(buf)) default: p.errorf("unrecognized complex size %d", typ.ByteSize) } case *dwarf.StructType: if typ.Kind != "struct" { // Could be "class" or "union". p.errorf("can't handle struct type %s", typ.Kind) return } p.printf("%s {", typ.String()) for i, field := range typ.Field { if i != 0 { p.printf(", ") } p.printValueAt(field.Type, a+uint64(field.ByteOffset)) } p.printf("}") case *dwarf.ArrayType: p.printArrayAt(typ, a) case *dwarf.InterfaceType: p.printInterfaceAt(typ, a) case *dwarf.MapType: p.printMapAt(typ, a) case *dwarf.ChanType: p.printChannelAt(typ, a) case *dwarf.SliceType: p.printSliceAt(typ, a) case *dwarf.StringType: p.printStringAt(typ, a) case *dwarf.TypedefType: p.printValueAt(typ.Type, a) case *dwarf.FuncType: p.printf("%v @%#x ", typ, a) case *dwarf.VoidType: p.printf("void") default: p.errorf("unimplemented type %v", typ) } }