Browse Source

sim: rewrite memory-region overlapping helper

problem:
  when the following memory region is specified
  -m0x00410000:0x1000,
    0x00410200:0x1000,
    0x00410400:0x1000,
    0x00410600:0x1000,
    0x00410800:0x1000,
    0x00411000:0x1000,
    0x00412000:0x1000,
    0x00413000:0x1000,
    0x00414000:0x1000

  The error is
    ERROR (duplicate_node_names): Duplicate node name /memory@410
    ERROR (duplicate_node_names): Duplicate node name /memory@410
    ERROR (duplicate_node_names): Duplicate node name /memory@410
    ERROR (duplicate_node_names): Duplicate node name /memory@410
    ERROR (duplicate_node_names): Duplicate node name /memory@410
    ERROR (duplicate_node_names): Duplicate node name /memory@410
    ERROR: Input tree has errors, aborting (use -f to force output)

cause:
  the merge_overlapping_memory_regions works not well in partial overlap case

change:
   1. use forward way to avoid weird reverse iterator behavior in C++
   2. use address but not page number since the base addresses are
      all aligned in make_mems

Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
pull/699/head
Chih-Min Chao 5 years ago
parent
commit
d99db79e38
  1. 39
      spike_main/spike.cc

39
spike_main/spike.cc

@ -114,26 +114,25 @@ void merge_overlapping_memory_regions(std::vector<std::pair<reg_t, mem_t*>>& mem
// check the user specified memory regions and merge the overlapping or // check the user specified memory regions and merge the overlapping or
// eliminate the containing parts // eliminate the containing parts
std::sort(mems.begin(), mems.end(), sort_mem_region); std::sort(mems.begin(), mems.end(), sort_mem_region);
reg_t start_page = 0, end_page = 0; std::vector<std::pair<reg_t, mem_t*>>::iterator it = mems.begin() + 1;
std::vector<std::pair<reg_t, mem_t*>>::reverse_iterator it = mems.rbegin();
std::vector<std::pair<reg_t, mem_t*>>::reverse_iterator _it = mems.rbegin(); while (it != mems.end()) {
for(; it != mems.rend(); ++it) { reg_t start = prev(it)->first;
reg_t _start_page = it->first/PGSIZE; reg_t end = prev(it)->first + prev(it)->second->size();
reg_t _end_page = _start_page + it->second->size()/PGSIZE; reg_t start2 = it->first;
if (_start_page >= start_page && _end_page <= end_page) { reg_t end2 = it->first + it->second->size();
// contains
mems.erase(std::next(it).base()); //contains -> remove
}else if ( _start_page < start_page && _end_page > start_page) { if (start2 >= start && end2 <= end) {
// overlapping it = mems.erase(it);
_it->first = _start_page; //parital overlapped -> extend
if (_end_page > end_page) } else if (start2 >= start && start2 < end) {
end_page = _end_page; delete prev(it)->second;
mems.erase(std::next(it).base()); prev(it)->second = new mem_t(std::max(end, end2) - start);
}else { it = mems.erase(it);
_it = it; // no overlapping -> keep it
start_page = _start_page; } else {
end_page = _end_page; it++;
assert(start_page < end_page);
} }
} }
} }

Loading…
Cancel
Save