@@ -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) {
@@ -2799,9 +2830,8 @@ void build_rmap_load_map(std::shared_ptr<load_map_item>load_map, range_map<uint3
2799
2830
try {
2800
2831
rmap.insert (range (e.runtime_address , e.runtime_address + e.size ), e.storage_address );
2801
2832
} catch (command_failure&) {
2802
- // Overlapping memory ranges are permitted in a load_map, so empty the range map and then add the entry
2803
- rmap.empty ();
2804
- rmap.insert (range (e.runtime_address , e.runtime_address + e.size ), e.storage_address );
2833
+ // Overlapping memory ranges are permitted in a load_map, so overwrite overlapping range
2834
+ rmap.insert_overwrite (range (e.runtime_address , e.runtime_address + e.size ), e.storage_address );
2805
2835
}
2806
2836
}
2807
2837
}
0 commit comments