@@ -246,8 +246,39 @@ template <typename T> struct range_map {
246
246
}
247
247
}
248
248
249
- void empty() {
250
- m.clear();
249
+ void insert_overwrite(const range& r, T t) {
250
+ if (r.to != r.from) {
251
+ assert(r.to > r.from);
252
+ // insert overlapping entry, and overwrite any it overlaps
253
+
254
+ // avoid modifying m while iterating through it
255
+ vector<uint32_t> to_erase;
256
+ vector<pair<uint32_t, pair<uint32_t, T>>> to_add;
257
+
258
+ auto f = m.upper_bound(r.from); // first element that starts after r.from
259
+ if (f != m.begin()) f--; // back up, to catch element that starts on or before r.from
260
+ for(; f != m.end() && f->first < r.to; f++) { // loop till we can't possibly overlap
261
+ range r2(f->first, f->second.first);
262
+ T r2off = f->second.second;
263
+ if (r2.intersects(r)) {
264
+ // remove existing r2
265
+ to_erase.push_back(r2.from);
266
+ if (r2.from < r.from) {
267
+ // add r2 which ends at start of r
268
+ to_add.push_back(std::make_pair(r2.from, std::make_pair(r.from, r2off)));
269
+ }
270
+ if (r2.to > r.to) {
271
+ // add r2 which starts at end of r
272
+ to_add.push_back(std::make_pair(r.to, std::make_pair(r2.to, r2off + (r.to - r2.from))));
273
+ }
274
+ }
275
+ }
276
+ for (auto k : to_erase) m.erase(k);
277
+ for (auto v : to_add) m.insert(v);
278
+
279
+ // finally, add the new entry
280
+ m.insert(std::make_pair(r.from, std::make_pair(r.to, t)));
281
+ }
251
282
}
252
283
253
284
pair<mapping, T> get(uint32_t p) {
@@ -2808,9 +2839,8 @@ void build_rmap_load_map(std::shared_ptr<load_map_item>load_map, range_map<uint3
2808
2839
try {
2809
2840
rmap.insert(range(e.runtime_address, e.runtime_address + e.size), e.storage_address);
2810
2841
} catch (command_failure&) {
2811
- // Overlapping memory ranges are permitted in a load_map, so empty the range map and then add the entry
2812
- rmap.empty();
2813
- rmap.insert(range(e.runtime_address, e.runtime_address + e.size), e.storage_address);
2842
+ // Overlapping memory ranges are permitted in a load_map, so overwrite overlapping range
2843
+ rmap.insert_overwrite(range(e.runtime_address, e.runtime_address + e.size), e.storage_address);
2814
2844
}
2815
2845
}
2816
2846
}
0 commit comments