提交 182f8050 编写于 作者: A aarzilli 提交者: Derek Parker

proc: Use MemoryReader inside memoryReadWriter

上级 329bc7e6
......@@ -9,15 +9,6 @@ import (
"sync"
)
// MemoryReader is like io.ReaderAt, but the offset is a uintptr so that it
// can address all of 64-bit memory.
// Redundant with memoryReadWriter but more easily suited to working with
// the standard io package.
type MemoryReader interface {
// ReadMemory is just like io.ReaderAt.ReadAt.
ReadMemory(buf []byte, addr uintptr) (n int, err error)
}
// A SplicedMemory represents a memory space formed from multiple regions,
// each of which may override previously regions. For example, in the following
// core, the program text was loaded at 0x400000:
......@@ -203,13 +194,12 @@ func (p *CoreProcess) BinInfo() *BinaryInfo {
return &p.bi
}
func (thread *CoreThread) readMemory(addr uintptr, size int) (data []byte, err error) {
data = make([]byte, size)
n, err := thread.p.core.ReadMemory(data, addr)
func (thread *CoreThread) ReadMemory(data []byte, addr uintptr) (n int, err error) {
n, err = thread.p.core.ReadMemory(data, addr)
if err == nil && n != len(data) {
err = ErrShortRead
}
return data, err
return n, err
}
func (thread *CoreThread) writeMemory(addr uintptr, data []byte) (int, error) {
......
......@@ -45,7 +45,8 @@ func Disassemble(dbp DisassembleInfo, g *G, startPC, endPC uint64) ([]AsmInstruc
}
func disassemble(memrw memoryReadWriter, regs Registers, breakpoints map[uint64]*Breakpoint, bi *BinaryInfo, startPC, endPC uint64) ([]AsmInstruction, error) {
mem, err := memrw.readMemory(uintptr(startPC), int(endPC-startPC))
mem := make([]byte, int(endPC-startPC))
_, err := memrw.ReadMemory(mem, uintptr(startPC))
if err != nil {
return nil, err
}
......
......@@ -96,7 +96,8 @@ func resolveCallArg(inst *ArchInst, currentGoroutine bool, regs Registers, mem m
}
addr := uintptr(int64(base) + int64(index*uint64(arg.Scale)) + arg.Disp)
//TODO: should this always be 64 bits instead of inst.MemBytes?
pcbytes, err := mem.readMemory(addr, inst.MemBytes)
pcbytes := make([]byte, inst.MemBytes)
_, err := mem.ReadMemory(pcbytes, addr)
if err != nil {
return nil
}
......
......@@ -841,8 +841,12 @@ func (p *GdbserverProcess) setCurrentBreakpoints() error {
return nil
}
func (t *GdbserverThread) readMemory(addr uintptr, size int) (data []byte, err error) {
return t.p.conn.readMemory(addr, size)
func (t *GdbserverThread) ReadMemory(data []byte, addr uintptr) (n int, err error) {
err = t.p.conn.readMemory(data, addr)
if err != nil {
return 0, err
}
return len(data), nil
}
func (t *GdbserverThread) writeMemory(addr uintptr, data []byte) (written int, err error) {
......@@ -1028,7 +1032,8 @@ func (t *GdbserverThread) reloadGAtPC() error {
}
}
savedcode, err := t.readMemory(uintptr(pc), len(movinstr))
savedcode := make([]byte, len(movinstr))
_, err := t.ReadMemory(savedcode, uintptr(pc))
if err != nil {
return err
}
......
......@@ -778,8 +778,9 @@ func (conn *gdbConn) appendThreadSelector(threadID string) {
}
// executes 'm' (read memory) command
func (conn *gdbConn) readMemory(addr uintptr, size int) (data []byte, err error) {
data = make([]byte, 0, size)
func (conn *gdbConn) readMemory(data []byte, addr uintptr) error {
size := len(data)
data = data[:0]
for size > 0 {
conn.outbuf.Reset()
......@@ -794,7 +795,7 @@ func (conn *gdbConn) readMemory(addr uintptr, size int) (data []byte, err error)
fmt.Fprintf(&conn.outbuf, "$m%x,%x", addr+uintptr(len(data)), sz)
resp, err := conn.exec(conn.outbuf.Bytes(), "memory read")
if err != nil {
return nil, err
return err
}
for i := 0; i < len(resp); i += 2 {
......@@ -802,7 +803,7 @@ func (conn *gdbConn) readMemory(addr uintptr, size int) (data []byte, err error)
data = append(data, uint8(n))
}
}
return data, nil
return nil
}
// executes 'M' (write memory) command
......
......@@ -2,8 +2,17 @@ package proc
const cacheEnabled = true
// MemoryReader is like io.ReaderAt, but the offset is a uintptr so that it
// can address all of 64-bit memory.
// Redundant with memoryReadWriter but more easily suited to working with
// the standard io package.
type MemoryReader interface {
// ReadMemory is just like io.ReaderAt.ReadAt.
ReadMemory(buf []byte, addr uintptr) (n int, err error)
}
type memoryReadWriter interface {
readMemory(addr uintptr, size int) (data []byte, err error)
MemoryReader
writeMemory(addr uintptr, data []byte) (written int, err error)
}
......@@ -17,14 +26,13 @@ func (m *memCache) contains(addr uintptr, size int) bool {
return addr >= m.cacheAddr && addr <= (m.cacheAddr+uintptr(len(m.cache)-size))
}
func (m *memCache) readMemory(addr uintptr, size int) (data []byte, err error) {
if m.contains(addr, size) {
d := make([]byte, size)
copy(d, m.cache[addr-m.cacheAddr:])
return d, nil
func (m *memCache) ReadMemory(data []byte, addr uintptr) (n int, err error) {
if m.contains(addr, len(data)) {
copy(data, m.cache[addr-m.cacheAddr:])
return len(data), nil
}
return m.mem.readMemory(addr, size)
return m.mem.ReadMemory(data, addr)
}
func (m *memCache) writeMemory(addr uintptr, data []byte) (written int, err error) {
......@@ -42,14 +50,16 @@ func cacheMemory(mem memoryReadWriter, addr uintptr, size int) memoryReadWriter
if cacheMem.contains(addr, size) {
return mem
} else {
cache, err := cacheMem.mem.readMemory(addr, size)
cache := make([]byte, size)
_, err := cacheMem.mem.ReadMemory(cache, addr)
if err != nil {
return mem
}
return &memCache{addr, cache, mem}
}
}
cache, err := mem.readMemory(addr, size)
cache := make([]byte, size)
_, err := mem.ReadMemory(cache, addr)
if err != nil {
return mem
}
......
......@@ -142,7 +142,8 @@ const (
func loadName(bi *BinaryInfo, addr uintptr, mem memoryReadWriter) (name, tag string, pkgpathoff int32, err error) {
off := addr
namedata, err := mem.readMemory(off, 3)
namedata := make([]byte, 3)
_, err = mem.ReadMemory(namedata, off)
off += 3
if err != nil {
return "", "", 0, err
......@@ -150,7 +151,8 @@ func loadName(bi *BinaryInfo, addr uintptr, mem memoryReadWriter) (name, tag str
namelen := uint16(namedata[1]<<8) | uint16(namedata[2])
rawstr, err := mem.readMemory(off, int(namelen))
rawstr := make([]byte, int(namelen))
_, err = mem.ReadMemory(rawstr, off)
off += uintptr(namelen)
if err != nil {
return "", "", 0, err
......@@ -159,14 +161,16 @@ func loadName(bi *BinaryInfo, addr uintptr, mem memoryReadWriter) (name, tag str
name = string(rawstr)
if namedata[0]&nameflagHasTag != 0 {
taglendata, err := mem.readMemory(off, 2)
taglendata := make([]byte, 2)
_, err = mem.ReadMemory(taglendata, off)
off += 2
if err != nil {
return "", "", 0, err
}
taglen := uint16(taglendata[0]<<8) | uint16(taglendata[1])
rawstr, err := mem.readMemory(off, int(taglen))
rawstr := make([]byte, int(taglen))
_, err = mem.ReadMemory(rawstr, off)
off += uintptr(taglen)
if err != nil {
return "", "", 0, err
......@@ -176,7 +180,8 @@ func loadName(bi *BinaryInfo, addr uintptr, mem memoryReadWriter) (name, tag str
}
if namedata[0]&nameflagHasPkg != 0 {
pkgdata, err := mem.readMemory(off, 4)
pkgdata := make([]byte, 4)
_, err = mem.ReadMemory(pkgdata, off)
if err != nil {
return "", "", 0, err
}
......
......@@ -282,7 +282,8 @@ func (dbp *Process) SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Exp
}
thread := dbp.threads[tid]
originalData, err := thread.readMemory(uintptr(addr), dbp.bi.arch.BreakpointSize())
originalData := make([]byte, dbp.bi.arch.BreakpointSize())
_, err := thread.ReadMemory(originalData, uintptr(addr))
if err != nil {
return nil, err
}
......@@ -707,7 +708,8 @@ func GoroutinesInfo(dbp EvalScopeConvertible) ([]*G, error) {
if err != nil {
return nil, err
}
allglenBytes, err := dbp.CurrentThread().readMemory(uintptr(addr), 8)
allglenBytes := make([]byte, 8)
_, err = dbp.CurrentThread().ReadMemory(allglenBytes, uintptr(addr))
if err != nil {
return nil, err
}
......@@ -722,7 +724,8 @@ func GoroutinesInfo(dbp EvalScopeConvertible) ([]*G, error) {
return nil, err
}
}
faddr, err := dbp.CurrentThread().readMemory(uintptr(allgentryaddr), dbp.BinInfo().arch.PtrSize())
faddr := make([]byte, dbp.BinInfo().arch.PtrSize())
_, err = dbp.CurrentThread().ReadMemory(faddr, uintptr(allgentryaddr))
allgptr := binary.LittleEndian.Uint64(faddr)
for i := uint64(0); i < allglen; i++ {
......
......@@ -135,7 +135,9 @@ func getRegisters(p IProcess, t *testing.T) Registers {
}
func dataAtAddr(thread memoryReadWriter, addr uint64) ([]byte, error) {
return thread.readMemory(uintptr(addr), 1)
data := make([]byte, 1)
_, err := thread.ReadMemory(data, uintptr(addr))
return data, err
}
func assertNoError(err error, t testing.TB, s string) {
......
......@@ -330,7 +330,8 @@ func (dbp *Process) waitForDebugEvent(flags waitForDebugEventFlags) (threadID, e
// this exception anymore.
atbp := true
if thread, found := dbp.threads[tid]; found {
if data, err := thread.readMemory(exception.ExceptionRecord.ExceptionAddress, dbp.bi.arch.BreakpointSize()); err == nil {
data := make([]byte, dbp.bi.arch.BreakpointSize())
if _, err := thread.ReadMemory(data, exception.ExceptionRecord.ExceptionAddress); err == nil {
instr := dbp.bi.arch.BreakpointInstruction()
for i := range instr {
if data[i] != instr[i] {
......
......@@ -385,7 +385,8 @@ func getGVariable(thread IThread) (*Variable, error) {
gaddr, hasgaddr := regs.GAddr()
if !hasgaddr {
gaddrbs, err := thread.readMemory(uintptr(regs.TLS()+arch.GStructOffset()), arch.PtrSize())
gaddrbs := make([]byte, arch.PtrSize())
_, err := thread.ReadMemory(gaddrbs, uintptr(regs.TLS()+arch.GStructOffset()))
if err != nil {
return nil, err
}
......
......@@ -119,20 +119,19 @@ func (t *Thread) writeMemory(addr uintptr, data []byte) (int, error) {
return len(data), nil
}
func (t *Thread) readMemory(addr uintptr, size int) ([]byte, error) {
if size == 0 {
return nil, nil
func (t *Thread) ReadMemory(buf []byte, addr uintptr) (int, error) {
if len(buf) == 0 {
return 0, nil
}
var (
buf = make([]byte, size)
vmData = unsafe.Pointer(&buf[0])
vmAddr = C.mach_vm_address_t(addr)
length = C.mach_msg_type_number_t(size)
length = C.mach_msg_type_number_t(len(buf))
)
ret := C.read_memory(t.dbp.os.task, vmAddr, vmData, length)
if ret < 0 {
return nil, fmt.Errorf("could not read memory")
return 0, fmt.Errorf("could not read memory")
}
return buf, nil
return len(buf), nil
}
......@@ -102,11 +102,10 @@ func (t *Thread) writeMemory(addr uintptr, data []byte) (written int, err error)
return
}
func (t *Thread) readMemory(addr uintptr, size int) (data []byte, err error) {
if size == 0 {
func (t *Thread) ReadMemory(data []byte, addr uintptr) (n int, err error) {
if len(data) == 0 {
return
}
data = make([]byte, size)
t.dbp.execPtraceFunc(func() { _, err = sys.PtracePeekData(t.ID, addr, data) })
return
}
......@@ -138,15 +138,14 @@ func (t *Thread) writeMemory(addr uintptr, data []byte) (int, error) {
return int(count), nil
}
func (t *Thread) readMemory(addr uintptr, size int) ([]byte, error) {
if size == 0 {
return nil, nil
func (t *Thread) ReadMemory(buf []byte, addr uintptr) (int, error) {
if len(buf) == 0 {
return 0, nil
}
var count uintptr
buf := make([]byte, size)
err := _ReadProcessMemory(t.dbp.os.hProcess, addr, &buf[0], uintptr(size), &count)
if err != nil {
return nil, err
err := _ReadProcessMemory(t.dbp.os.hProcess, addr, &buf[0], uintptr(len(buf)), &count)
if err == nil && count != uintptr(len(buf)) {
err = ErrShortRead
}
return buf[:count], nil
return int(count), err
}
......@@ -367,7 +367,8 @@ func (gvar *Variable) parseG() (*G, error) {
_, deref := gvar.RealType.(*dwarf.PtrType)
if deref {
gaddrbytes, err := mem.readMemory(uintptr(gaddr), gvar.bi.arch.PtrSize())
gaddrbytes := make([]byte, gvar.bi.arch.PtrSize())
_, err := mem.ReadMemory(gaddrbytes, uintptr(gaddr))
if err != nil {
return nil, fmt.Errorf("error derefing *G %s", err)
}
......@@ -886,7 +887,8 @@ func (v *Variable) loadValueInternal(recurseLevel int, cfg LoadConfig) {
v.Value = constant.MakeUint64(val)
case reflect.Bool:
val, err := v.mem.readMemory(v.Addr, 1)
val := make([]byte, 1)
_, err := v.mem.ReadMemory(val, v.Addr)
v.Unreadable = err
if err == nil {
v.Value = constant.MakeBool(val[0] != 0)
......@@ -946,7 +948,8 @@ func readStringInfo(mem memoryReadWriter, arch Arch, addr uintptr) (uintptr, int
mem = cacheMemory(mem, addr, arch.PtrSize()*2)
// read len
val, err := mem.readMemory(addr+uintptr(arch.PtrSize()), arch.PtrSize())
val := make([]byte, arch.PtrSize())
_, err := mem.ReadMemory(val, addr+uintptr(arch.PtrSize()))
if err != nil {
return 0, 0, fmt.Errorf("could not read string len %s", err)
}
......@@ -956,7 +959,7 @@ func readStringInfo(mem memoryReadWriter, arch Arch, addr uintptr) (uintptr, int
}
// read addr
val, err = mem.readMemory(addr, arch.PtrSize())
_, err = mem.ReadMemory(val, addr)
if err != nil {
return 0, 0, fmt.Errorf("could not read string pointer %s", err)
}
......@@ -974,7 +977,8 @@ func readStringValue(mem memoryReadWriter, addr uintptr, strlen int64, cfg LoadC
count = int64(cfg.MaxStringLen)
}
val, err := mem.readMemory(addr, int(count))
val := make([]byte, int(count))
_, err := mem.ReadMemory(val, addr)
if err != nil {
return "", fmt.Errorf("could not read string at %#v due to %s", addr, err)
}
......@@ -1102,7 +1106,8 @@ func (v *Variable) writeComplex(real, imag float64, size int64) error {
func readIntRaw(mem memoryReadWriter, addr uintptr, size int64) (int64, error) {
var n int64
val, err := mem.readMemory(addr, int(size))
val := make([]byte, int(size))
_, err := mem.ReadMemory(val, addr)
if err != nil {
return 0, err
}
......@@ -1142,7 +1147,8 @@ func (v *Variable) writeUint(value uint64, size int64) error {
func readUintRaw(mem memoryReadWriter, addr uintptr, size int64) (uint64, error) {
var n uint64
val, err := mem.readMemory(addr, int(size))
val := make([]byte, int(size))
_, err := mem.ReadMemory(val, addr)
if err != nil {
return 0, err
}
......@@ -1162,7 +1168,8 @@ func readUintRaw(mem memoryReadWriter, addr uintptr, size int64) (uint64, error)
}
func (v *Variable) readFloatRaw(size int64) (float64, error) {
val, err := v.mem.readMemory(v.Addr, int(size))
val := make([]byte, int(size))
_, err := v.mem.ReadMemory(val, v.Addr)
if err != nil {
return 0.0, err
}
......@@ -1206,7 +1213,8 @@ func (v *Variable) writeBool(value bool) error {
}
func (v *Variable) readFunctionPtr() {
val, err := v.mem.readMemory(v.Addr, v.bi.arch.PtrSize())
val := make([]byte, v.bi.arch.PtrSize())
_, err := v.mem.ReadMemory(val, v.Addr)
if err != nil {
v.Unreadable = err
return
......@@ -1220,7 +1228,7 @@ func (v *Variable) readFunctionPtr() {
return
}
val, err = v.mem.readMemory(fnaddr, v.bi.arch.PtrSize())
_, err = v.mem.ReadMemory(val, fnaddr)
if err != nil {
v.Unreadable = err
return
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册