-// This is djb2:
-typedef uint64_t mc_hash_t;
-#define MC_HASH_INIT ((uint64_t)5381)
-
-// #define MC_HASH(hash, value) hash = (((hash << 5) + hash) + (uint64_t) value)
-#define MC_HASH(hash, value) \
- { hash = (((hash << 5) + hash) + (uint64_t) value);\
- XBT_DEBUG("%s:%i: %" PRIx64 " -> %" PRIx64, __FILE__, __LINE__, (uint64_t) value, hash); }
-
-// ***** Hash state
-
-#if 0
-typedef struct s_mc_hashing_state {
- // Set of pointers/addresses already processed (avoid loops):
- mc_address_set_t handled_addresses;
-} mc_hashing_state;
-
-void mc_hash_state_init(mc_hashing_state * state);
-void mc_hash_state_destroy(mc_hashing_state * state);
-
-void mc_hash_state_init(mc_hashing_state * state)
-{
- state->handled_addresses = mc_address_set_new();
-}
-
-void mc_hash_state_destroy(mc_hashing_state * state)
-{
- mc_address_set_free(&state->handled_addresses);
-}
-
-// TODO, detect and avoid loops
-
-static bool mc_ignored(const void *address, size_t size)
-{
- mc_heap_ignore_region_t region;
- unsigned int cursor = 0;
- const void *end = (char *) address + size;
- xbt_dynar_foreach(mc_heap_comparison_ignore, cursor, region) {
- void *istart = region->address;
- void *iend = (char *) region->address + region->size;
-
- if (address >= istart && address < iend && end >= istart && end < iend)
- return true;
- }
-
- return false;
-}
-
-static void mc_hash_binary(mc_hash_t * hash, const void *s, size_t len)
-{
- const char *p = (const char*) s;
- for (size_t i = 0; i != len; ++i) {
- MC_HASH(*hash, p[i]);
- }
-}
-
-/** \brief Compute a hash for a given value of a given type
- *
- * We try to be very conservative (do not hash too ambiguous things).
- *
- * \param address address of the variable
- * \param type type of the variable
- * */
-static void mc_hash_value(mc_hash_t * hash, mc_hashing_state * state,
- mc_object_info_t info, const void *address,
- dw_type_t type)
-{
- mc_process_t process = &mc_model_checker->process();
-top:
-
- switch (type->type) {
-
- // Not relevant, do nothing:
- case DW_TAG_unspecified_type:
- return;
-
- // Simple case, hash this has binary:
- case DW_TAG_base_type:
- case DW_TAG_enumeration_type:
- {
- if (mc_ignored(address, 1))
- return;
- mc_hash_binary(hash, address, type->byte_size);
- return;
- }
-
- case DW_TAG_array_type:
- {
- if (mc_ignored(address, type->byte_size))
- return;
-
- long element_count = type->element_count;
- dw_type_t subtype = type->subtype;
- if (subtype == NULL) {
- XBT_DEBUG("Hash array without subtype");
- return;
- }
- int i;
- for (i = 0; i != element_count; ++i) {
- XBT_DEBUG("Hash array element %i", i);
- void *subaddress = ((char *) address) + i * subtype->byte_size;
- mc_hash_value(hash, state, info, subaddress, subtype);
- }
- return;
- }
-
- // Get the raw type:
- case DW_TAG_typedef:
- case DW_TAG_volatile_type:
- case DW_TAG_const_type:
- case DW_TAG_restrict_type:
- {
- type = type->subtype;
- if (type == NULL)
- return;
- else
- goto top;
- }
-
- case DW_TAG_structure_type:
- case DW_TAG_class_type:
- {
- if (mc_ignored(address, type->byte_size))
- return;
-
- unsigned int cursor = 0;
- dw_type_t member;
- xbt_dynar_foreach(type->members, cursor, member) {
- XBT_DEBUG("Hash struct member %s", member->name);
- if (type->subtype == NULL)
- return;
- void *member_variable = mc_member_resolve(address, type, member, NULL);
- mc_hash_value(hash, state, info, member_variable, type->subtype);
- }
- return;
- }
-
- // Pointer, we hash a single value but it might be an array.
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- {
- if (mc_ignored(address, 1))
- return;
-
- void *pointed = *(void **) address;
- if (pointed == NULL) {
- XBT_DEBUG("Hashed pinter is NULL");
- return;
- }
- // Avoid loops:
- if (mc_address_test(state->handled_addresses, pointed)) {
- XBT_DEBUG("Hashed pointed data %p already hashed", pointed);
- return;
- }
- mc_address_add(state->handled_addresses, pointed);
-
- // Anything outside the R/W segments and the heap is not hashed:
- bool valid_pointer = (pointed >= (void *) binary_info->start_rw
- && pointed <= (void *) binary_info->end_rw)
- || (pointed >= (void *) libsimgrid_info->start_rw
- && pointed <= (void *) libsimgrid_info->end_rw)
- || (pointed >= process->heap_address
- && pointed < (void *) ((const char *) process->heap_address + STD_HEAP_SIZE));
- if (!valid_pointer) {
- XBT_DEBUG("Hashed pointed data %p is in an ignored range", pointed);
- return;
- }