func()

in internal/core/mapping.go [178:246]


func (s *splicedMemory) Add(min, max Address, perm Perm, f *os.File, off int64) {
	if max-min <= 0 {
		return
	}

	// Align max.
	if max%pageSize != 0 {
		max = (max + pageSize) & ^(pageSize - 1)
	}
	// Align min.
	if gap := min % pageSize; gap != 0 {
		off -= int64(gap)
		min -= gap
	}

	newMappings := make([]*Mapping, 0, len(s.mappings)+1)
	add := func(m *Mapping) {
		if m.Size() <= 0 {
			return
		}
		newMappings = append(newMappings, m)
	}

	inserted := false
	for _, entry := range s.mappings {
		switch {
		case entry.max < min: // entry is completely before the new region.
			add(entry)
		case max < entry.min: // entry is completely after the new region.
			if !inserted {
				add(&Mapping{min: min, max: max, perm: perm, f: f, off: off})
				inserted = true
			}
			add(entry)
		case min <= entry.min && entry.max <= max:
			// entry is completely overwritten by the new region. Drop.
		case entry.min <= min && entry.max <= max:
			// new region overwrites the end of the entry.
			entry.max = min
			add(entry)
		case min <= entry.min && max <= entry.max:
			// new region overwrites the begining of the entry.
			if !inserted {
				add(&Mapping{min: min, max: max, perm: perm, f: f, off: off})
				inserted = true
			}
			entry.off += int64(max - entry.min)
			entry.min = max
			add(entry)
		case entry.min < min && max < entry.max:
			// new region punches a hole in the entry.
			entry2 := *entry

			entry.max = min
			entry2.off += int64(max - entry.min)
			entry2.min = max
			add(entry)
			add(&Mapping{min: min, max: max, perm: perm, f: f, off: off})
			add(&entry2)
			inserted = true
		default:
			panic(fmt.Sprintf("Unhandled case: existing entry is (min:0x%x max:0x%x), new entry is (min:0x%x max:0x%x)", entry.min, entry.max, min, max))
		}
	}
	if !inserted {
		add(&Mapping{min: min, max: max, perm: perm, f: f, off: off})
	}
	s.mappings = newMappings
}