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
}