Beispiel #1
0
func prettyTypeName(typ dwarf.Type) string {
	if typ == nil {
		return ""
	}
	r := typ.String()
	if r == "*void" {
		return "unsafe.Pointer"
	}
	return r
}
Beispiel #2
0
// 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
}
Beispiel #3
0
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
}
Beispiel #4
0
// 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)
	}
}