blob: c273b075e402f591e423eb65120a14f11585b685 [file] [log] [blame]
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package server
import (
"fmt"
"golang.org/x/debug/dwarf"
"golang.org/x/debug/ogle/program"
)
// value peeks the program's memory at the given address, parsing it as a value of type t.
func (s *Server) value(t dwarf.Type, addr uint64) (program.Value, error) {
// readInt reads the memory for an n-byte integer or unsigned integer.
readInt := func(n int64) ([]byte, error) {
switch n {
case 1, 2, 4, 8:
default:
return nil, fmt.Errorf("invalid size: %d", n)
}
buf := make([]byte, n)
if err := s.peek(uintptr(addr), buf); err != nil {
return nil, err
}
return buf, nil
}
switch t := t.(type) {
case *dwarf.IntType:
bs := t.Common().ByteSize
buf, err := readInt(bs)
if err != nil {
return nil, fmt.Errorf("reading integer: %s", err)
}
x := s.arch.IntN(buf)
switch bs {
case 1:
return int8(x), nil
case 2:
return int16(x), nil
case 4:
return int32(x), nil
case 8:
return int64(x), nil
}
case *dwarf.UintType:
bs := t.Common().ByteSize
buf, err := readInt(bs)
if err != nil {
return nil, fmt.Errorf("reading unsigned integer: %s", err)
}
x := s.arch.UintN(buf)
switch bs {
case 1:
return uint8(x), nil
case 2:
return uint16(x), nil
case 4:
return uint32(x), nil
case 8:
return uint64(x), nil
}
// TODO: more types
}
return nil, fmt.Errorf("Unsupported type %T", t)
}