- int res;
-
- do {
- switch (type->type) {
- case DW_TAG_unspecified_type:
- return 1;
-
- 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 {