mem.go 1.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
package proc

const cacheEnabled = true

type memoryReadWriter interface {
	readMemory(addr uintptr, size int) (data []byte, err error)
	writeMemory(addr uintptr, data []byte) (written int, err error)
}

type memCache struct {
	cacheAddr uintptr
	cache     []byte
	mem       memoryReadWriter
}

func (m *memCache) contains(addr uintptr, size int) bool {
17
	return addr >= m.cacheAddr && addr <= (m.cacheAddr+uintptr(len(m.cache)-size))
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
}

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
	}

	return m.mem.readMemory(addr, size)
}

func (m *memCache) writeMemory(addr uintptr, data []byte) (written int, err error) {
	return m.mem.writeMemory(addr, data)
}

func cacheMemory(mem memoryReadWriter, addr uintptr, size int) memoryReadWriter {
	if !cacheEnabled {
		return mem
	}
38 39 40
	if size <= 0 {
		return mem
	}
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
	if cacheMem, isCache := mem.(*memCache); isCache {
		if cacheMem.contains(addr, size) {
			return mem
		} else {
			cache, err := cacheMem.mem.readMemory(addr, size)
			if err != nil {
				return mem
			}
			return &memCache{addr, cache, mem}
		}
	}
	cache, err := mem.readMemory(addr, size)
	if err != nil {
		return mem
	}
	return &memCache{addr, cache, mem}
}