Skip to content

Commit 8e9eaba

Browse files
committed
Better fix for #210
Instead of emptying the range_map, just overwrite overlapping entries, like the bootrom would do when loading the load_map
1 parent 7080fdf commit 8e9eaba

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

main.cpp

+35-5
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,39 @@ template <typename T> struct range_map {
246246
}
247247
}
248248

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+
}
251282
}
252283

253284
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
28082839
try {
28092840
rmap.insert(range(e.runtime_address, e.runtime_address + e.size), e.storage_address);
28102841
} 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);
28142844
}
28152845
}
28162846
}

0 commit comments

Comments
 (0)