Example #1
0
func (p *memImage) traceMem(u models.Usercorn, addr uint64, data []byte) {
	if len(data) > p.blockSize {
		firstLen := (addr+uint64(p.blockSize)-1) & ^uint64(p.blockSize-1) - addr
		if firstLen > 0 {
			p.traceMem(u, addr, data[:firstLen])
		}
		for i := firstLen; i < uint64(len(data)); i += uint64(p.blockSize) {
			p.traceMem(u, addr+uint64(i), data[i:i+uint64(p.blockSize)])
		}
		return
	}

	i, m, had := p.find(addr)
	if !had {
		aligned := addr & ^uint64(p.blockSize-1)
		r := &region{
			Addr: aligned,
			Size: uint64(p.blockSize),
			Data: make([]byte, p.blockSize),
		}
		for _, v := range u.Mappings() {
			if v.Contains(addr) {
				r.Desc = v.Desc
				r.Prot = v.Prot
				if v.File != nil {
					r.Filename = v.File.Name
				}
				break
			}
		}
		p.maps = append(p.maps, r)
		sort.Sort(RegionAddrSort(p.maps))

		i, m, _ = p.find(addr)
		p.resize()
	}
	off := (addr - m.Addr)
	dst := m.Data[off:]
	for i, v := range data {
		if (dst[i] == 0) != (v == 0) {
			if v != 0 {
				m.ByteCount++
			} else {
				m.ByteCount--
			}
		}
		dst[i] = v
	}
	if m.ByteCount == 0 {
		p.maps = append(p.maps[:i], p.maps[i+1:]...)
		p.resize()
	}
}