- return (addr_pointed1 != addr_pointed2);
- }
- break;
- }
- case DW_TAG_structure_type:
- case DW_TAG_class_type:
- for (simgrid::mc::Member& member : type->members) {
- void *member1 = simgrid::dwarf::resolve_member(
- real_area1, type, &member, snapshot1, process_index);
- void *member2 = simgrid::dwarf::resolve_member(
- real_area2, type, &member, snapshot2, process_index);
- mc_mem_region_t subregion1 = mc_get_region_hinted(member1, snapshot1, process_index, region1);
- mc_mem_region_t subregion2 = mc_get_region_hinted(member2, snapshot2, process_index, region2);
- res =
- compare_areas_with_type(state, process_index,
- member1, snapshot1, subregion1,
- member2, snapshot2, subregion2,
- member.type, pointer_level);
- if (res == 1)
- return res;
+ case DW_TAG_base_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_union_type:
+ return MC_snapshot_region_memcmp(real_area1, region1, real_area2, region2, type->byte_size) != 0;
+ case DW_TAG_typedef:
+ case DW_TAG_volatile_type:
+ case DW_TAG_const_type:
+ // Poor man's TCO:
+ type = type->subtype;
+ continue; // restart
+ case DW_TAG_array_type:
+ subtype = type->subtype;
+ switch (subtype->type) {
+ case DW_TAG_unspecified_type:
+ return 1;
+
+ case DW_TAG_base_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_class_type:
+ case DW_TAG_union_type:
+ if (subtype->full_type)
+ subtype = subtype->full_type;
+ elm_size = subtype->byte_size;
+ break;
+ case DW_TAG_const_type:
+ case DW_TAG_typedef:
+ case DW_TAG_volatile_type:
+ subsubtype = subtype->subtype;
+ if (subsubtype->full_type)
+ subsubtype = subsubtype->full_type;
+ elm_size = subsubtype->byte_size;
+ break;
+ default:
+ return 0;
+ break;
+ }
+ for (i = 0; i < type->element_count; i++) {
+ size_t off = i * elm_size;
+ res = compare_areas_with_type(state, process_index, (char*)real_area1 + off, snapshot1, region1,
+ (char*)real_area2 + off, snapshot2, region2, type->subtype, pointer_level);
+ if (res == 1)
+ return res;
+ }
+ break;
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type: {
+ void* addr_pointed1 = MC_region_read_pointer(region1, real_area1);
+ void* addr_pointed2 = MC_region_read_pointer(region2, real_area2);
+
+ if (type->subtype && type->subtype->type == DW_TAG_subroutine_type)
+ return (addr_pointed1 != addr_pointed2);
+ if (addr_pointed1 == nullptr && addr_pointed2 == nullptr)
+ return 0;
+ if (addr_pointed1 == nullptr || addr_pointed2 == nullptr)
+ return 1;
+ if (not state.compared_pointers.insert(std::make_pair(addr_pointed1, addr_pointed2)).second)
+ return 0;
+
+ pointer_level++;
+
+ // Some cases are not handled here:
+ // * the pointers lead to different areas (one to the heap, the other to the RW segment ...)
+ // * a pointer leads to the read-only segment of the current object
+ // * a pointer lead to a different ELF object
+
+ if (addr_pointed1 > process->heap_address && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1)) {
+ if (not(addr_pointed2 > process->heap_address && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2)))
+ return 1;
+ // The pointers are both in the heap:
+ return simgrid::mc::compare_heap_area(state, process_index, addr_pointed1, addr_pointed2, snapshot1,
+ snapshot2, nullptr, type->subtype, pointer_level);
+
+ } else if (region1->contain(simgrid::mc::remote(addr_pointed1))) {
+ // The pointers are both in the current object R/W segment:
+ if (not region2->contain(simgrid::mc::remote(addr_pointed2)))
+ return 1;
+ if (not type->type_id)
+ return (addr_pointed1 != addr_pointed2);
+ else
+ return compare_areas_with_type(state, process_index, addr_pointed1, snapshot1, region1, addr_pointed2,
+ snapshot2, region2, type->subtype, pointer_level);
+ } else {
+
+ // TODO, We do not handle very well the case where
+ // it belongs to a different (non-heap) region from the current one.
+
+ return (addr_pointed1 != addr_pointed2);
+ }
+ break;
+ }
+ case DW_TAG_structure_type:
+ case DW_TAG_class_type:
+ for (simgrid::mc::Member& member : type->members) {
+ void* member1 = simgrid::dwarf::resolve_member(real_area1, type, &member, snapshot1, process_index);
+ void* member2 = simgrid::dwarf::resolve_member(real_area2, type, &member, snapshot2, process_index);
+ mc_mem_region_t subregion1 = mc_get_region_hinted(member1, snapshot1, process_index, region1);
+ mc_mem_region_t subregion2 = mc_get_region_hinted(member2, snapshot2, process_index, region2);
+ res = compare_areas_with_type(state, process_index, member1, snapshot1, subregion1, member2, snapshot2,
+ subregion2, member.type, pointer_level);
+ if (res == 1)
+ return res;
+ }
+ break;
+ case DW_TAG_subroutine_type:
+ return -1;
+ break;
+ default:
+ XBT_VERB("Unknown case: %d", type->type);
+ break;