From 7c4cc145c41e6f4e0b7841c84d780074a04b6f35 Mon Sep 17 00:00:00 2001 From: Marion Guthmuller Date: Fri, 5 Oct 2012 19:12:11 +0200 Subject: [PATCH] Get local variables in binary and libsimgrid.so and their values for each system state and compare them for state equality detection (to complete if optimizations are enabled) --- src/mc/mc_checkpoint.c | 245 +++++++++- src/mc/mc_compare.c | 102 ++-- src/mc/mc_global.c | 1000 ++++++++++++++++++++++++---------------- src/mc/mc_private.h | 53 ++- 4 files changed, 948 insertions(+), 452 deletions(-) diff --git a/src/mc/mc_checkpoint.c b/src/mc/mc_checkpoint.c index 6f815ccd81..411747a309 100644 --- a/src/mc/mc_checkpoint.c +++ b/src/mc/mc_checkpoint.c @@ -18,6 +18,7 @@ void *start_text_libsimgrid; void *start_plt, *end_plt; char *libsimgrid_path; void *start_data_libsimgrid; +void *start_text_binary; static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size); static void MC_region_restore(mc_mem_region_t reg); @@ -27,8 +28,9 @@ static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type, void *start static void add_value(xbt_dynar_t *list, const char *type, unsigned long int val); static xbt_dynar_t take_snapshot_stacks(void *heap); -static void get_local_variables_values(xbt_dynar_t *all_variables, stack_region_t stack, void *heap); +static xbt_strbuff_t get_local_variables_values(stack_region_t stack, void *heap); static void print_local_variables_values(xbt_dynar_t all_variables); +static void *get_stack_pointer(stack_region_t stack, void *heap); static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size) { @@ -97,6 +99,7 @@ void MC_take_snapshot(mc_snapshot_t snapshot) void MC_take_snapshot_liveness(mc_snapshot_t snapshot) { + unsigned int i = 0; s_map_region_t reg; memory_map_t maps = get_memory_map(); @@ -130,6 +133,10 @@ void MC_take_snapshot_liveness(mc_snapshot_t snapshot) if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){ start_text_libsimgrid = reg.start_addr; libsimgrid_path = strdup(maps->regions[i].pathname); + }else{ + if (!memcmp(basename(maps->regions[i].pathname), basename(xbt_binary_name), strlen(basename(xbt_binary_name)))){ + start_text_binary = reg.start_addr; + } } } } @@ -218,3 +225,239 @@ void get_plt_section(){ } +static void add_value(xbt_dynar_t *list, const char *type, unsigned long int val){ + variable_value_t value = xbt_new0(s_variable_value_t, 1); + value->type = strdup(type); + if(strcmp(type, "value") == 0){ + value->value.res = val; + }else{ + value->value.address = (void *)val; + } + xbt_dynar_push(*list, &value); +} + +static xbt_dynar_t take_snapshot_stacks(void *heap){ + + xbt_dynar_t res = xbt_dynar_new(sizeof(s_mc_snapshot_stack_t), NULL); + + unsigned int cursor1 = 0; + stack_region_t current_stack; + + xbt_dynar_foreach(stacks_areas, cursor1, current_stack){ + mc_snapshot_stack_t st = xbt_new(s_mc_snapshot_stack_t, 1); + st->local_variables = get_local_variables_values(current_stack, heap); + st->stack_pointer = get_stack_pointer(current_stack, heap); + xbt_dynar_push(res, &st); + } + + return res; + +} + +static void *get_stack_pointer(stack_region_t stack, void *heap){ + + unw_cursor_t c; + int ret; + unw_word_t sp; + + ret = unw_init_local(&c, (unw_context_t *)&(((smx_ctx_sysv_t)(stack->address))->uc)); + if(ret < 0){ + XBT_INFO("unw_init_local failed"); + xbt_abort(); + } + + unw_get_reg(&c, UNW_REG_SP, &sp); + + return ((char *)heap + (size_t)(((char *)((long)sp) - (char*)std_heap))); + +} + +static xbt_strbuff_t get_local_variables_values(stack_region_t stack, void *heap){ + + unw_cursor_t c; + int ret; + char *stack_name; + + char buf[512], frame_name[256]; + + ret = unw_init_local(&c, (unw_context_t *)&(((smx_ctx_sysv_t)(stack->address))->uc)); + if(ret < 0){ + XBT_INFO("unw_init_local failed"); + xbt_abort(); + } + + stack_name = strdup(((smx_process_t)((smx_ctx_sysv_t)(stack->address))->super.data)->name); + + unw_word_t ip, sp, off; + dw_frame_t frame; + + xbt_dynar_t compose = xbt_dynar_new(sizeof(variable_value_t), NULL); + + xbt_strbuff_t variables = xbt_strbuff_new(); + xbt_dict_cursor_t dict_cursor; + char *variable_name; + dw_local_variable_t current_variable; + unsigned int cursor = 0, cursor2 = 0; + dw_location_entry_t entry = NULL; + dw_location_t location_entry = NULL; + unw_word_t res; + int frame_found = 0; + void *frame_pointer_address = NULL; + long true_ip; + + while(ret >= 0){ + + unw_get_reg(&c, UNW_REG_IP, &ip); + unw_get_reg(&c, UNW_REG_SP, &sp); + + buf[0] = '\0'; + if (unw_get_proc_name (&c, frame_name, sizeof (frame_name), &off) == 0){ + if (off) + snprintf (buf, sizeof (buf), "<%s+0x%lx>", frame_name, (long) off); + else + snprintf (buf, sizeof (buf), "<%s>", frame_name); + + } + + xbt_strbuff_append(variables, bprintf("ip=%-32s\n", buf)); + + frame = xbt_dict_get_or_null(mc_local_variables, frame_name); + + if(frame == NULL){ + ret = unw_step(&c); + continue; + } + + true_ip = (long)frame->low_pc + (long)off; + + /* Get frame pointer */ + switch(frame->frame_base->type){ + case e_dw_loclist: + while((cursor < xbt_dynar_length(frame->frame_base->location.loclist)) && frame_found == 0){ + entry = xbt_dynar_get_as(frame->frame_base->location.loclist, cursor, dw_location_entry_t); + if((true_ip >= entry->lowpc) && (true_ip < entry->highpc)){ + frame_found = 1; + switch(entry->location->type){ + case e_dw_compose: + xbt_dynar_reset(compose); + cursor2 = 0; + while(cursor2 < xbt_dynar_length(entry->location->location.compose)){ + location_entry = xbt_dynar_get_as(entry->location->location.compose, cursor2, dw_location_t); + switch(location_entry->type){ + case e_dw_register: + unw_get_reg(&c, location_entry->location.reg, &res); + add_value(&compose, "address", (long)res); + break; + case e_dw_bregister_op: + unw_get_reg(&c, location_entry->location.breg_op.reg, &res); + add_value(&compose, "address", (long)res + location_entry->location.breg_op.offset); + break; + default: + xbt_dynar_reset(compose); + break; + } + cursor2++; + } + + if(xbt_dynar_length(compose) > 0){ + frame_pointer_address = xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1, variable_value_t)->value.address ; + } + break; + default : + frame_pointer_address = NULL; + break; + } + } + cursor++; + } + break; + default : + frame_pointer_address = NULL; + break; + } + + frame_found = 0; + cursor = 0; + + //XBT_INFO("Frame %s", frame->name); + + xbt_dict_foreach(frame->variables, dict_cursor, variable_name, current_variable){ + if(current_variable->location != NULL){ + switch(current_variable->location->type){ + case e_dw_compose: + xbt_dynar_reset(compose); + cursor = 0; + while(cursor < xbt_dynar_length(current_variable->location->location.compose)){ + location_entry = xbt_dynar_get_as(current_variable->location->location.compose, cursor, dw_location_t); + switch(location_entry->type){ + case e_dw_register: + unw_get_reg(&c, location_entry->location.reg, &res); + add_value(&compose, "value", (long)res); + break; + case e_dw_bregister_op: + unw_get_reg(&c, location_entry->location.breg_op.reg, &res); + add_value(&compose, "address", (long)res + location_entry->location.breg_op.offset); + break; + case e_dw_fbregister_op: + if(frame_pointer_address != NULL) + add_value(&compose, "address", (long)((char *)frame_pointer_address + location_entry->location.fbreg_op)); + break; + default: + xbt_dynar_reset(compose); + break; + } + cursor++; + } + + if(xbt_dynar_length(compose) > 0){ + if(strcmp(xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1, variable_value_t)->type, "value") == 0){ + //XBT_INFO("Variable : %s - value : %lx", current_variable->name, xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1, variable_value_t)->value.res); + xbt_strbuff_append(variables, bprintf("%s=%lx\n", current_variable->name, xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1, variable_value_t)->value.res)); + }else{ + if(*((void**)xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1,variable_value_t)->value.address) == NULL){ + //XBT_INFO("Variable : %s - address : NULL", current_variable->name); + xbt_strbuff_append(variables, bprintf("%s=NULL\n", current_variable->name)); + }else if(((long)*((void**)xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1,variable_value_t)->value.address) > 0xffffffff) || ((long)*((void**)xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1,variable_value_t)->value.address) < (long)start_text_binary)){ + //XBT_INFO("Variable : %s - value : %d", current_variable->name, (int)(long long int)*((void**)xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1, variable_value_t)->value.address)); + xbt_strbuff_append(variables, bprintf("%s=%d\n", current_variable->name, (int)(long long int)*((void**)xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1, variable_value_t)->value.address))); + }else{ + //XBT_INFO("Variable : %s - address : %p", current_variable->name, *((void**)xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1, variable_value_t)->value.address)); + xbt_strbuff_append(variables, bprintf("%s=%p\n", current_variable->name, *((void**)xbt_dynar_get_as(compose, xbt_dynar_length(compose) - 1, variable_value_t)->value.address))); + } + } + }else{ + //XBT_INFO("Variable %s undefined", current_variable->name); + xbt_strbuff_append(variables, bprintf("%s=undefined\n", current_variable->name)); + } + break; + default : + break; + } + }else{ + //XBT_INFO("Variable : %s, no location", current_variable->name); + xbt_strbuff_append(variables, bprintf("%s=undefined\n", current_variable->name)); + } + } + + ret = unw_step(&c); + + //XBT_INFO(" "); + + } + + free(stack_name); + + return variables; + +} + +static void print_local_variables_values(xbt_dynar_t all_variables){ + + unsigned cursor = 0; + mc_snapshot_stack_t stack; + + xbt_dynar_foreach(all_variables, cursor, stack){ + XBT_INFO("%s", stack->local_variables->data); + } +} + diff --git a/src/mc/mc_compare.c b/src/mc/mc_compare.c index 36ce55730c..1ca61f0b7a 100644 --- a/src/mc/mc_compare.c +++ b/src/mc/mc_compare.c @@ -14,11 +14,12 @@ static int data_program_region_compare(void *d1, void *d2, size_t size); static int data_libsimgrid_region_compare(void *d1, void *d2, size_t size); static int heap_region_compare(void *d1, void *d2, size_t size); -static int compare_local_variables(xbt_strbuff_t s1, xbt_strbuff_t s2); static int compare_stack(stack_region_t s1, stack_region_t s2, void *sp1, void *sp2, void *heap1, void *heap2, xbt_dynar_t equals); static int is_heap_equality(xbt_dynar_t equals, void *a1, void *a2); static size_t ignore(void *address); +static int compare_local_variables(char *s1, char *s2, xbt_dynar_t heap_equals); + static size_t ignore(void *address){ unsigned int cursor = 0; int start = 0; @@ -112,7 +113,7 @@ int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){ void *heap1 = NULL, *heap2 = NULL; if(s1->num_reg != s2->num_reg){ - XBT_DEBUG("Different num_reg (s1 = %u, s2 = %u)", s1->num_reg, s2->num_reg); + XBT_INFO("Different num_reg (s1 = %u, s2 = %u)", s1->num_reg, s2->num_reg); return 1; } @@ -127,15 +128,15 @@ int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){ case 0 : /* Compare heapregion */ if(s1->regions[i]->size != s2->regions[i]->size){ - XBT_DEBUG("Different size of heap (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size); + XBT_INFO("Different size of heap (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size); return 1; } if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){ - XBT_DEBUG("Different start addr of heap (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr); + XBT_INFO("Different start addr of heap (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr); return 1; } if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[i]->data, (xbt_mheap_t)s2->regions[i]->data, &stacks1, &stacks2, &equals)){ - XBT_DEBUG("Different heap (mmalloc_compare)"); + XBT_INFO("Different heap (mmalloc_compare)"); return 1; } heap1 = s1->regions[i]->data; @@ -144,15 +145,15 @@ int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){ case 1 : /* Compare data libsimgrid region */ if(s1->regions[i]->size != s2->regions[i]->size){ - XBT_DEBUG("Different size of libsimgrid (data) (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size); + XBT_INFO("Different size of libsimgrid (data) (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size); return 1; } if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){ - XBT_DEBUG("Different start addr of libsimgrid (data) (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr); + XBT_INFO("Different start addr of libsimgrid (data) (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr); return 1; } if(data_libsimgrid_region_compare(s1->regions[i]->data, s2->regions[i]->data, s1->regions[i]->size) != 0){ - XBT_DEBUG("Different memcmp for data in libsimgrid"); + XBT_INFO("Different memcmp for data in libsimgrid"); return 1; } break; @@ -160,15 +161,15 @@ int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){ case 2 : /* Compare data program region */ if(s1->regions[i]->size != s2->regions[i]->size){ - XBT_DEBUG("Different size of data program (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size); + XBT_INFO("Different size of data program (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size); return 1; } if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){ - XBT_DEBUG("Different start addr of data program (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr); + XBT_INFO("Different start addr of data program (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr); return 1; } if(data_program_region_compare(s1->regions[i]->data, s2->regions[i]->data, s1->regions[i]->size) != 0){ - XBT_DEBUG("Different memcmp for data in program"); + XBT_INFO("Different memcmp for data in program"); return 1; } break; @@ -178,29 +179,69 @@ int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){ } /* Stacks comparison */ - unsigned int cursor = 1; + unsigned int cursor = 1, cursor2 = 0; stack_region_t stack_region1, stack_region2; void *sp1, *sp2; - int diff = 0; + int diff = 0, diff_local = 0; + heap_equality_t equality; while(cursor < xbt_dynar_length(stacks1)){ - XBT_DEBUG("Stack %d", cursor + 1); + XBT_INFO("Stack %d", cursor + 1); stack_region1 = (stack_region_t)(xbt_dynar_get_as(stacks1, cursor, stack_region_t)); stack_region2 = (stack_region_t)(xbt_dynar_get_as(stacks2, cursor, stack_region_t)); sp1 = ((mc_snapshot_stack_t)xbt_dynar_get_as(s1->stacks, cursor, mc_snapshot_stack_t))->stack_pointer; sp2 = ((mc_snapshot_stack_t)xbt_dynar_get_as(s2->stacks, cursor, mc_snapshot_stack_t))->stack_pointer; - diff += compare_stack(stack_region1, stack_region2, sp1, sp2, heap1, heap2, equals); + diff = compare_stack(stack_region1, stack_region2, sp1, sp2, heap1, heap2, equals); + + if(diff >0){ + diff_local = compare_local_variables(((mc_snapshot_stack_t)xbt_dynar_get_as(s1->stacks, cursor, mc_snapshot_stack_t))->local_variables->data, ((mc_snapshot_stack_t)xbt_dynar_get_as(s2->stacks, cursor, mc_snapshot_stack_t))->local_variables->data, equals); + if(diff_local > 0){ + XBT_INFO("Hamming distance between stacks : %d", diff); + return 1; + }else{ + XBT_INFO("Local variables are equals in stack %d", cursor + 1); + } + }else{ + XBT_INFO("Same stacks"); + } cursor++; } - XBT_DEBUG("Hamming distance between stacks : %d", diff); - if(diff>0) - return 1; - return 0; } +static int compare_local_variables(char *s1, char *s2, xbt_dynar_t heap_equals){ + + xbt_dynar_t tokens1 = xbt_str_split(s1, NULL); + xbt_dynar_t tokens2 = xbt_str_split(s2, NULL); + + xbt_dynar_t s_tokens1, s_tokens2; + unsigned int cursor = 0; + void *addr1, *addr2; + + int diff = 0; + + while(cursor < xbt_dynar_length(tokens1)){ + s_tokens1 = xbt_str_split(xbt_dynar_get_as(tokens1, cursor, char *), "="); + s_tokens2 = xbt_str_split(xbt_dynar_get_as(tokens2, cursor, char *), "="); + if(xbt_dynar_length(s_tokens1) > 1 && xbt_dynar_length(s_tokens2) > 1){ + if(strcmp(xbt_dynar_get_as(s_tokens1, 1, char *), xbt_dynar_get_as(s_tokens2, 1, char *)) != 0){ + addr1 = (void *) strtoul(xbt_dynar_get_as(s_tokens1, 1, char *), NULL, 16); + addr2 = (void *) strtoul(xbt_dynar_get_as(s_tokens2, 1, char *), NULL, 16); + if(is_heap_equality(heap_equals, addr1, addr2) == 0){ + XBT_INFO("Variable %s is different between stacks : %s - %s", xbt_dynar_get_as(s_tokens1, 0, char *), xbt_dynar_get_as(s_tokens1, 1, char *), xbt_dynar_get_as(s_tokens2, 1, char *)); + diff++; + } + } + } + cursor++; + } + + return diff; + +} + static int is_heap_equality(xbt_dynar_t equals, void *a1, void *a2){ unsigned int cursor = 0; @@ -232,9 +273,9 @@ static int is_heap_equality(xbt_dynar_t equals, void *a1, void *a2){ static int compare_stack(stack_region_t s1, stack_region_t s2, void *sp1, void *sp2, void *heap1, void *heap2, xbt_dynar_t equals){ - int k = 0, nb_diff = 0; - long size_used1 = (long)s1->size - (long)((char*)sp1 - (char*)s1->address); - long size_used2 = (long)s2->size - (long)((char*)sp2 - (char*)s2->address); + size_t k = 0, nb_diff = 0; + size_t size_used1 = s1->size - ((char*)sp1 - (char*)s1->address); + size_t size_used2 = s2->size - ((char*)sp2 - (char*)s2->address); int pointer_align; void *addr_pointed1 = NULL, *addr_pointed2 = NULL; @@ -249,11 +290,11 @@ static int compare_stack(stack_region_t s1, stack_region_t s2, void *sp1, void * if(is_heap_equality(equals, addr_pointed1, addr_pointed2) == 0){ if((addr_pointed1 > std_heap) && (addr_pointed1 < (void *)((char *)std_heap + STD_HEAP_SIZE)) && (addr_pointed2 > std_heap) && (addr_pointed2 < (void *)((char *)std_heap + STD_HEAP_SIZE))){ if(is_free_area(addr_pointed1, (xbt_mheap_t)heap1) == 0 || is_free_area(addr_pointed2, (xbt_mheap_t)heap2) == 0){ - XBT_DEBUG("Difference at offset %d (%p - %p)", k, (char *)s1->address + s1->size - k, (char *)s2->address + s2->size - k); + //XBT_INFO("Difference at offset %zu (%p - %p)", k, (char *)s1->address + s1->size - k, (char *)s2->address + s2->size - k); nb_diff++; } }else{ - XBT_DEBUG("Difference at offset %d (%p - %p)", k, (char *)s1->address + s1->size - k, (char *)s2->address + s2->size - k); + //XBT_INFO("Difference at offset %zu (%p - %p)", k, (char *)s1->address + s1->size - k, (char *)s2->address + s2->size - k); nb_diff++; } } @@ -262,20 +303,9 @@ static int compare_stack(stack_region_t s1, stack_region_t s2, void *sp1, void * } }else{ - XBT_DEBUG("Different size used between stacks"); + XBT_INFO("Different size used between stacks"); return 1; } return nb_diff; } - -static int compare_local_variables(xbt_strbuff_t s1, xbt_strbuff_t s2){ - - if(strcmp(s1->data, s2->data) != 0){ - XBT_DEBUG("%s", s1->data); - XBT_DEBUG("%s", s2->data); - return 1; - } - - return 0; -} diff --git a/src/mc/mc_global.c b/src/mc/mc_global.c index a0906644cd..6a4b83b010 100644 --- a/src/mc/mc_global.c +++ b/src/mc/mc_global.c @@ -14,6 +14,7 @@ #include "xbt/fifo.h" #include "mc_private.h" #include "xbt/automaton.h" +#include "xbt/dict.h" XBT_LOG_NEW_CATEGORY(mc, "All MC categories"); XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_global, mc, @@ -169,7 +170,7 @@ void MC_modelcheck_liveness(){ raw_mem_set = (mmalloc_get_current_heap() == raw_heap); /* init stuff */ - XBT_DEBUG("Start init mc"); + XBT_INFO("Start init mc"); mc_time = xbt_new0(double, simix_process_maxpid); @@ -184,10 +185,19 @@ void MC_modelcheck_liveness(){ iteration of the model-checker (in RAW memory) */ MC_SET_RAW_MEM; - + + char *ls_path = get_libsimgrid_path(); + + mc_local_variables = xbt_dict_new_homogeneous(NULL); + /* Get local variables in binary for state equality detection */ - MC_get_binary_local_variables(); + xbt_dict_t binary_location_list = MC_get_location_list(xbt_binary_name); + MC_get_local_variables(xbt_binary_name, binary_location_list, &mc_local_variables); + /* Get local variables in libsimgrid for state equality detection */ + xbt_dict_t libsimgrid_location_list = MC_get_location_list(ls_path); + MC_get_local_variables(ls_path, libsimgrid_location_list, &mc_local_variables); + /* Initialize statistics */ mc_stats_pair = xbt_new0(s_mc_stats_pair_t, 1); @@ -706,331 +716,683 @@ void MC_new_stack_area(void *stack, char *name){ /************ DWARF ***********/ -static void MC_get_binary_local_variables(){ +xbt_dict_t MC_get_location_list(const char *elf_file){ - mc_binary_local_variables = xbt_dynar_new(sizeof(dw_frame_t), NULL); + char *command = bprintf("objdump -Wo %s", elf_file); - char *command = bprintf("dwarfdump -i %s", xbt_binary_name); - - FILE* fp = popen(command, "r"); + FILE *fp = popen(command, "r"); if(fp == NULL) - perror("popen failed"); + perror("popen for objdump failed"); - char *line = NULL, *tmp_line = NULL, *tmp_location, *frame_name = NULL; + int debug = 0; /*Detect if the program has been compiled with -g */ + + xbt_dict_t location_list = xbt_dict_new_homogeneous(NULL); + char *line = NULL, *loc_expr = NULL; ssize_t read; size_t n = 0; - int valid_variable = 1, valid_frame = 1; - char *node_type, *location_type, *variable_name = NULL, *lowpc, *highpc; + int cursor_remove; xbt_dynar_t split = NULL; - void *low_pc = NULL, *old_low_pc = NULL; + while ((read = getline(&line, &n, fp)) != -1) { - int compile_unit_found = 0; /* Detect if the program has been compiled with -g */ + /* Wipeout the new line character */ + line[read - 1] = '\0'; - read = getline(&line, &n, fp); + xbt_str_trim(line, NULL); + + if(n == 0) + continue; - while (read != -1) { + if(strlen(line) == 0) + continue; + + if(debug == 0){ + + if(strncmp(line, elf_file, strlen(elf_file)) == 0) + continue; + + if(strncmp(line, "Contents", 8) == 0) + continue; + + if(strncmp(line, "Offset", 6) == 0){ + debug = 1; + continue; + } + } + + if(debug == 0){ + XBT_INFO("Your program must be compiled with -g"); + xbt_abort(); + } + + xbt_dynar_t loclist = xbt_dynar_new(sizeof(dw_location_entry_t), NULL); + + xbt_str_strip_spaces(line); + split = xbt_str_split(line, " "); + + while(read != -1 && strcmp("lowpc = strtoul((char *)xbt_dynar_get_as(split, 1, char *), NULL, 16); + new_entry->highpc = strtoul((char *)xbt_dynar_get_as(split, 2, char *), NULL, 16); + + cursor_remove =0; + while(cursor_remove < 3){ + xbt_dynar_remove_at(split, 0, NULL); + cursor_remove++; + } + + loc_expr = xbt_str_join(split, " "); + xbt_str_ltrim(loc_expr, "("); + xbt_str_rtrim(loc_expr, ")"); + new_entry->location = get_location(NULL, loc_expr); + + xbt_dynar_push(loclist, &new_entry); + + xbt_dynar_free(&split); + free(loc_expr); + + read = getline(&line, &n, fp); + if(read != -1){ + line[read - 1] = '\0'; + xbt_str_strip_spaces(line); + split = xbt_str_split(line, " "); + } + + } + + + char *key = bprintf("%d", (int)strtoul((char *)xbt_dynar_get_as(split, 0, char *), NULL, 16)); + xbt_dict_set(location_list, key, loclist, NULL); + + xbt_dynar_free(&split); + + } + + free(line); + free(command); + pclose(fp); + + return location_list; +} + +char *get_libsimgrid_path(){ + char *command = bprintf("ldd %s", xbt_binary_name); + + FILE *fp = popen(command, "r"); + if(fp == NULL) + perror("popen for ldd failed"); + + char *line; + ssize_t read; + size_t n = 0; + xbt_dynar_t split; + + while((read = getline(&line, &n, fp)) != -1){ + if(n == 0) continue; /* Wipeout the new line character */ line[read - 1] = '\0'; + + xbt_str_strip_spaces(line); + xbt_str_ltrim(line, NULL); + split = xbt_str_split(line, " "); + + if(strncmp((char *)xbt_dynar_get_as(split, 0, char *), "libsimgrid.so", 13) == 0){ + free(line); + free(command); + pclose(fp); + return ((char *)xbt_dynar_get_as(split, 2, char *)); + } + + xbt_dynar_free(&split); - if(line[0] == '<'){ + } - /* If the program hasn't been compiled with -g, no symbol (line starting with '<' ) found */ - compile_unit_found = 1; + free(line); + free(command); + pclose(fp); - /* Get node type */ - strtok(line, " "); - strtok(NULL, " "); - node_type = strtok(NULL, " "); + return NULL; + +} - if(strcmp(node_type, "DW_TAG_subprogram") == 0){ /* New frame */ +static dw_frame_t get_frame_by_offset(xbt_dict_t all_variables, unsigned long int offset){ - read = getline(&line, &n, fp); + xbt_dict_cursor_t cursor = NULL; + char *name; + dw_frame_t res; - while(read != -1 && line[0] != '<'){ + xbt_dict_foreach(all_variables, cursor, name, res) { + if(offset >= res->start && offset < res->end) + return res; + } - if(n == 0) - continue; + return NULL; + +} - node_type = strtok(line, " "); +void MC_get_local_variables(const char *elf_file, xbt_dict_t location_list, xbt_dict_t *all_variables){ - if(node_type != NULL && strcmp(node_type, "DW_AT_name") == 0){ + char *command = bprintf("objdump -Wi %s", elf_file); + + FILE *fp = popen(command, "r"); - frame_name = strdup(strtok(NULL, " ")); - xbt_str_trim(frame_name, NULL); - xbt_str_trim(frame_name, "\""); - read = getline(&line, &n, fp); + if(fp == NULL) + perror("popen for objdump failed"); - }else if(node_type != NULL && strcmp(node_type, "DW_AT_frame_base") == 0){ + char *line = NULL, *origin, *abstract_origin, *current_frame = NULL; + ssize_t read =0; + size_t n = 0; + int valid_variable = 1; + char *node_type = NULL, *location_type = NULL, *variable_name = NULL, *loc_expr = NULL; + xbt_dynar_t split = NULL, split2 = NULL; - if(valid_frame == 1){ + xbt_dict_t variables_origin = xbt_dict_new_homogeneous(NULL); + xbt_dict_t subprograms_origin = xbt_dict_new_homogeneous(NULL); + char *subprogram_name = NULL, *subprogram_start = NULL, *subprogram_end = NULL; + int new_frame = 0, new_variable = 0; + dw_frame_t variable_frame, subroutine_frame = NULL; - dw_frame_t frame = xbt_new0(s_dw_frame_t, 1); - frame->name = strdup(frame_name); - frame->variables = xbt_dynar_new(sizeof(dw_local_variable_t), NULL); - frame->location = xbt_new0(s_dw_location_t, 1); - free(frame_name); - - location_type = strtok(NULL, " "); + read = getline(&line, &n, fp); - if(strcmp(location_type, "location->type = e_dw_loclist; - frame->location->location.loclist = xbt_dynar_new(sizeof(dw_location_entry_t), NULL); - - read = getline(&line, &n, fp); - xbt_str_ltrim(line, NULL); - - while(read != -1 && line[0] == '['){ + if(n == 0){ + read = getline(&line, &n, fp); + continue; + } + + /* Wipeout the new line character */ + line[read - 1] = '\0'; + + if(strlen(line) == 0){ + read = getline(&line, &n, fp); + continue; + } - strtok(line, "<"); - lowpc = strtok(NULL, "<"); - highpc = strtok(NULL, ">"); - tmp_location = strtok(NULL, ">"); - lowpc[strlen(lowpc) - 1] = '\0'; /* Remove last character '>' */ - - dw_location_entry_t new_entry = xbt_new0(s_dw_location_entry_t, 1); - - if(low_pc == NULL){ - strtok(lowpc, "="); - new_entry->lowpc = (void *) strtoul(strtok(NULL, "="), NULL, 16); - strtok(highpc, "="); - new_entry->highpc = (void *) strtoul(strtok(NULL, "="), NULL, 16); - }else{ - strtok(lowpc, "="); - old_low_pc = (void *)strtoul(strtok(NULL, "="), NULL, 16); - new_entry->lowpc = (char *)low_pc + (long)old_low_pc; - strtok(highpc, "="); - new_entry->highpc = (char*)low_pc + ((char *)((void *)strtoul(strtok(NULL, "="), NULL, 16)) - (char*)old_low_pc); - } - - new_entry->location = xbt_new0(s_dw_location_t, 1); - - get_location(tmp_location, new_entry->location); - - xbt_dynar_push(frame->location->location.loclist, &new_entry); + xbt_str_ltrim(line, NULL); + xbt_str_strip_spaces(line); + + if(line[0] != '<'){ + read = getline(&line, &n, fp); + continue; + } + + xbt_dynar_free(&split); + split = xbt_str_split(line, " "); - read = getline(&line, &n, fp); - xbt_str_ltrim(line, NULL); + /* Get node type */ + node_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *); - } + if(strcmp(node_type, "(DW_TAG_subprogram)") == 0){ /* New frame */ - }else{ - read = getline(&line, &n, fp); - frame->location->type = get_location(location_type, frame->location); + dw_frame_t frame = NULL; - } + strtok(xbt_dynar_get_as(split, 0, char *), "<"); + subprogram_start = strdup(strtok(NULL, "<")); + xbt_str_rtrim(subprogram_start, ">:"); - xbt_dynar_push(mc_binary_local_variables, &frame); + read = getline(&line, &n, fp); + + while(read != -1){ - }else{ + if(n == 0){ + read = getline(&line, &n, fp); + continue; + } - read = getline(&line, &n, fp); + /* Wipeout the new line character */ + line[read - 1] = '\0'; + + if(strlen(line) == 0){ + read = getline(&line, &n, fp); + continue; + } + + xbt_dynar_free(&split); + xbt_str_rtrim(line, NULL); + xbt_str_strip_spaces(line); + split = xbt_str_split(line, " "); + + node_type = xbt_dynar_get_as(split, 1, char *); - } - - }else if(node_type != NULL && (strcmp(node_type, "DW_AT_declaration") == 0 || strcmp(node_type, "DW_AT_abstract_origin") == 0 || strcmp(node_type, "DW_AT_artificial") == 0)){ + if(strncmp(node_type, "DW_AT_", 6) != 0) + break; + + if(strcmp(node_type, "DW_AT_sibling") == 0){ - read = getline(&line, &n, fp); - valid_frame = 0; + subprogram_end = strdup(xbt_dynar_get_as(split, 3, char*)); + xbt_str_ltrim(subprogram_end, "<0x"); + xbt_str_rtrim(subprogram_end, ">"); - }else{ + }else if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){ /* Frame already in dict */ + + new_frame = 0; + abstract_origin = strdup(xbt_dynar_get_as(split, 2, char*)); + xbt_str_ltrim(abstract_origin, "<0x"); + xbt_str_rtrim(abstract_origin, ">"); + subprogram_name = (char *)xbt_dict_get_or_null(subprograms_origin, abstract_origin); + frame = xbt_dict_get_or_null(*all_variables, subprogram_name); + + }else if(strcmp(node_type, "DW_AT_name") == 0){ + + new_frame = 1; + free(current_frame); + frame = xbt_new0(s_dw_frame_t, 1); + frame->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *)); + frame->variables = xbt_dict_new_homogeneous(NULL); + frame->frame_base = xbt_new0(s_dw_location_t, 1); + current_frame = strdup(frame->name); + + xbt_dict_set(subprograms_origin, subprogram_start, frame->name, NULL); + + }else if(strcmp(node_type, "DW_AT_frame_base") == 0){ + + location_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *); - read = getline(&line, &n, fp); + if(strcmp(location_type, "list)") == 0){ /* Search location in location list */ + + frame->frame_base = get_location(location_list, xbt_dynar_get_as(split, 3, char *)); + + }else{ + + xbt_str_strip_spaces(line); + split2 = xbt_str_split(line, "("); + xbt_dynar_remove_at(split2, 0, NULL); + loc_expr = xbt_str_join(split2, " "); + xbt_str_rtrim(loc_expr, ")"); + frame->frame_base = get_location(NULL, loc_expr); + xbt_dynar_free(&split2); } + + }else if(strcmp(node_type, "DW_AT_low_pc") == 0){ + + if(frame != NULL) + frame->low_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16); + + }else if(strcmp(node_type, "DW_AT_high_pc") == 0){ + + if(frame != NULL) + frame->high_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16); + + }else if(strcmp(node_type, "DW_AT_MIPS_linkage_name:") == 0){ + + free(frame->name); + free(current_frame); + frame->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *)); + current_frame = strdup(frame->name); + xbt_dict_set(subprograms_origin, subprogram_start, frame->name, NULL); } - - valid_frame = 1; - }else if(strcmp(node_type, "DW_TAG_variable") == 0){ /* New variable */ - read = getline(&line, &n, fp); - while(read != -1 && line[0] != '<'){ + } + + if(new_frame == 1){ + frame->start = strtoul(subprogram_start, NULL, 16); + if(subprogram_end != NULL) + frame->end = strtoul(subprogram_end, NULL, 16); + xbt_dict_set(*all_variables, frame->name, frame, NULL); + } - if(n == 0) - continue; + free(subprogram_start); + if(subprogram_end != NULL){ + free(subprogram_end); + subprogram_end = NULL; + } + - tmp_line = strdup(line); - - node_type = strtok(line, " "); + }else if(strcmp(node_type, "(DW_TAG_variable)") == 0){ /* New variable */ - if(node_type != NULL && strcmp(node_type, "DW_AT_name") == 0){ + dw_local_variable_t var = NULL; + + strtok(xbt_dynar_get_as(split, 0, char *), "<"); + origin = strdup(strtok(NULL, "<")); + xbt_str_rtrim(origin, ">:"); + + read = getline(&line, &n, fp); + + while(read != -1){ - variable_name = strdup(strtok(NULL, " ")); - xbt_str_trim(variable_name, NULL); - xbt_str_trim(variable_name, "\""); - read = getline(&line, &n, fp); - - }else if(node_type != NULL && strcmp(node_type, "DW_AT_location") == 0){ + if(n == 0){ + read = getline(&line, &n, fp); + continue; + } - if(valid_variable == 1){ + /* Wipeout the new line character */ + line[read - 1] = '\0'; - location_type = strtok(NULL, " "); + if(strlen(line) == 0){ + read = getline(&line, &n, fp); + continue; + } + + xbt_dynar_free(&split); + xbt_str_rtrim(line, NULL); + xbt_str_strip_spaces(line); + split = xbt_str_split(line, " "); + + node_type = xbt_dynar_get_as(split, 1, char *); - dw_local_variable_t variable = xbt_new0(s_dw_local_variable_t, 1); - variable->name = strdup(variable_name); - variable->location = xbt_new0(s_dw_location_t, 1); - free(variable_name); - - if(strcmp(location_type, "location->type = e_dw_loclist; - variable->location->location.loclist = xbt_dynar_new(sizeof(dw_location_entry_t), NULL); + if(strcmp(node_type, "DW_AT_name") == 0){ - read = getline(&line, &n, fp); - xbt_str_ltrim(line, NULL); - - while(read != -1 && line[0] == '['){ - - strtok(line, "<"); - lowpc = strtok(NULL, "<"); - highpc = strtok(NULL, ">"); - tmp_location = strtok(NULL, ">"); - lowpc[strlen(lowpc) - 1] = '\0'; /* Remove last character '>' */ - - dw_location_entry_t new_entry = xbt_new0(s_dw_location_entry_t, 1); - - if(low_pc == NULL){ - strtok(lowpc, "="); - new_entry->lowpc = (void *) strtoul(strtok(NULL, "="), NULL, 16); - strtok(highpc, "="); - new_entry->highpc = (void *) strtoul(strtok(NULL, "="), NULL, 16); - }else{ - strtok(lowpc, "="); - old_low_pc = (void *)strtoul(strtok(NULL, "="), NULL, 16); - new_entry->lowpc = (char *)low_pc + (long)old_low_pc; - strtok(highpc, "="); - new_entry->highpc = (char*)low_pc + ((char *)((void *)strtoul(strtok(NULL, "="), NULL, 16)) - (char*)old_low_pc); - } - - new_entry->location = xbt_new0(s_dw_location_t, 1); - - get_location(tmp_location, new_entry->location); - - xbt_dynar_push(variable->location->location.loclist, &new_entry); + new_variable = 1; + var = xbt_new0(s_dw_local_variable_t, 1); + var->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *)); - read = getline(&line, &n, fp); - xbt_str_ltrim(line, NULL); + xbt_dict_set(variables_origin, origin, var->name, NULL); + + }else if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){ - } - - }else{ - - xbt_str_strip_spaces(tmp_line); - split = xbt_str_split(tmp_line, " "); - xbt_dynar_remove_at(split, 0, NULL); - location_type = xbt_str_join(split, " "); - - variable->location->type = get_location(location_type, variable->location); - read = getline(&line, &n, fp); + new_variable = 0; + abstract_origin = xbt_dynar_get_as(split, 2, char *); + xbt_str_ltrim(abstract_origin, "<0x"); + xbt_str_rtrim(abstract_origin, ">"); + + variable_name = (char *)xbt_dict_get_or_null(variables_origin, abstract_origin); + variable_frame = get_frame_by_offset(*all_variables, strtoul(abstract_origin, NULL, 16)); + var = xbt_dict_get_or_null(variable_frame->variables, variable_name); - xbt_dynar_free(&split); - free(location_type); + }else if(strcmp(node_type, "DW_AT_location") == 0){ - } + if(valid_variable == 1 && var != NULL){ - xbt_dynar_push(((dw_frame_t)xbt_dynar_get_as(mc_binary_local_variables, xbt_dynar_length(mc_binary_local_variables) - 1, dw_frame_t))->variables, &variable); + var->location = xbt_new0(s_dw_location_t, 1); - }else{ + location_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *); + + if(strcmp(location_type, "list)") == 0){ /* Search location in location list */ - read = getline(&line, &n, fp); + var->location = get_location(location_list, xbt_dynar_get_as(split, 3, char *)); + + }else{ + + xbt_str_strip_spaces(line); + split2 = xbt_str_split(line, "("); + xbt_dynar_remove_at(split2, 0, NULL); + loc_expr = xbt_str_join(split2, " "); + xbt_str_rtrim(loc_expr, ")"); + var->location = get_location(NULL, loc_expr); + xbt_dynar_free(&split2); } + + } - }else if(node_type != NULL && (strcmp(node_type, "DW_AT_artificial") == 0 || strcmp(node_type, "DW_AT_external") == 0)){ + }else if(strcmp(node_type, "DW_AT_external") == 0){ - valid_variable = 0; - read = getline(&line, &n, fp); + valid_variable = 0; + + } - }else{ + read = getline(&line, &n, fp); + + } - read = getline(&line, &n, fp); + if(new_variable == 1 && valid_variable == 1){ + + variable_frame = xbt_dict_get_or_null(*all_variables, current_frame); + xbt_dict_set(variable_frame->variables, var->name, var, NULL); + } - } + valid_variable = 1; + new_variable = 0; - //free(tmp_line); - - } + }else if(strcmp(node_type, "(DW_TAG_inlined_subroutine)") == 0){ - valid_variable = 1; + strtok(xbt_dynar_get_as(split, 0, char *), "<"); + origin = strdup(strtok(NULL, "<")); + xbt_str_rtrim(origin, ">:"); - }else if(strcmp(node_type, "DW_TAG_compile_unit") == 0){ + read = getline(&line, &n, fp); - read = getline(&line, &n, fp); + while(read != -1){ + + /* Wipeout the new line character */ + line[read - 1] = '\0'; + + if(n == 0){ + read = getline(&line, &n, fp); + continue; + } + + if(strlen(line) == 0){ + read = getline(&line, &n, fp); + continue; + } + + xbt_dynar_free(&split); + xbt_str_rtrim(line, NULL); + xbt_str_strip_spaces(line); + split = xbt_str_split(line, " "); - while(read != -1 && line[0] != '<'){ - - if(n == 0) - continue; + if(strncmp(xbt_dynar_get_as(split, 1, char *), "DW_AT_", 6) != 0) + break; - node_type = strtok(line, " "); + node_type = xbt_dynar_get_as(split, 1, char *); + + if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){ + + origin = xbt_dynar_get_as(split, 2, char *); + xbt_str_ltrim(origin, "<0x"); + xbt_str_rtrim(origin, ">"); - if(node_type != NULL && strcmp(node_type, "DW_AT_low_pc") == 0){ - low_pc = (void *) strtoul(strtok(NULL, " "), NULL, 16); - } + subprogram_name = (char *)xbt_dict_get_or_null(subprograms_origin, origin); + subroutine_frame = xbt_dict_get_or_null(*all_variables, subprogram_name); + + }else if(strcmp(node_type, "DW_AT_low_pc") == 0){ - read = getline(&line, &n, fp); + subroutine_frame->low_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16); - } + }else if(strcmp(node_type, "DW_AT_high_pc") == 0){ - }else{ + subroutine_frame->high_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16); + } read = getline(&line, &n, fp); - + } - }else{ read = getline(&line, &n, fp); } - } - + + xbt_dynar_free(&split); free(line); free(command); pclose(fp); + +} - if(compile_unit_found == 0){ - XBT_INFO("Your program must be compiled with -g"); - xbt_abort(); - } +static dw_location_t get_location(xbt_dict_t location_list, char *expr){ - if(XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)) - print_local_variables(mc_binary_local_variables); + dw_location_t loc = xbt_new0(s_dw_location_t, 1); + + if(location_list != NULL){ + + char *key = bprintf("%d", (int)strtoul(expr, NULL, 16)); + loc->type = e_dw_loclist; + loc->location.loclist = (xbt_dynar_t)xbt_dict_get_or_null(location_list, key); + if(loc == NULL) + XBT_INFO("Key not found in loclist"); + return loc; + + }else{ + + int cursor = 0; + char *tok = NULL, *tok2 = NULL; + + xbt_dynar_t tokens1 = xbt_str_split(expr, ";"); + xbt_dynar_t tokens2; + + loc->type = e_dw_compose; + loc->location.compose = xbt_dynar_new(sizeof(dw_location_t), NULL); + + while(cursor < xbt_dynar_length(tokens1)){ + + tok = xbt_dynar_get_as(tokens1, cursor, char*); + tokens2 = xbt_str_split(tok, " "); + tok2 = xbt_dynar_get_as(tokens2, 0, char*); + + if(strncmp(tok2, "DW_OP_reg", 9) == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_register; + new_element->location.reg = atoi(strtok(tok2, "DW_OP_reg")); + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strcmp(tok2, "DW_OP_fbreg:") == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_fbregister_op; + new_element->location.fbreg_op = atoi(xbt_dynar_get_as(tokens2, 1, char*)); + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strncmp(tok2, "DW_OP_breg", 10) == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_bregister_op; + new_element->location.breg_op.reg = atoi(strtok(tok2, "DW_OP_breg")); + new_element->location.breg_op.offset = atoi(xbt_dynar_get_as(tokens2, 2, char*)); + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strncmp(tok2, "DW_OP_lit", 9) == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_lit; + new_element->location.lit = atoi(strtok(tok2, "DW_OP_lit")); + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strcmp(tok2, "DW_OP_piece:") == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_piece; + new_element->location.piece = atoi(xbt_dynar_get_as(tokens2, 1, char*)); + /*if(strlen(xbt_dynar_get_as(tokens2, 1, char*)) > 1) + new_element->location.piece = atoi(xbt_dynar_get_as(tokens2, 1, char*)); + else + new_element->location.piece = xbt_dynar_get_as(tokens2, 1, char*)[0] - '0';*/ + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strcmp(tok2, "DW_OP_plus_uconst:") == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_plus_uconst; + new_element->location.plus_uconst = atoi(xbt_dynar_get_as(tokens2, 1, char *)); + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strcmp(tok, "DW_OP_abs") == 0 || + strcmp(tok, "DW_OP_and") == 0 || + strcmp(tok, "DW_OP_div") == 0 || + strcmp(tok, "DW_OP_minus") == 0 || + strcmp(tok, "DW_OP_mod") == 0 || + strcmp(tok, "DW_OP_mul") == 0 || + strcmp(tok, "DW_OP_neg") == 0 || + strcmp(tok, "DW_OP_not") == 0 || + strcmp(tok, "DW_OP_or") == 0 || + strcmp(tok, "DW_OP_plus") == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_arithmetic; + new_element->location.arithmetic = strdup(strtok(tok2, "DW_OP_")); + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strcmp(tok, "DW_OP_stack_value") == 0){ + }else if(strcmp(tok2, "DW_OP_deref_size:") == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_deref; + new_element->location.deref_size = (unsigned int short) atoi(xbt_dynar_get_as(tokens2, 1, char*)); + /*if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1) + new_element->location.deref_size = atoi(xbt_dynar_get_as(tokens, cursor, char*)); + else + new_element->location.deref_size = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0';*/ + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strcmp(tok, "DW_OP_deref") == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_deref; + new_element->location.deref_size = sizeof(void *); + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strcmp(tok2, "DW_OP_constu:") == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_uconstant; + new_element->location.uconstant.bytes = 1; + new_element->location.uconstant.value = (unsigned long int)(atoi(xbt_dynar_get_as(tokens2, 1, char*))); + /*if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1) + new_element->location.uconstant.value = (unsigned long int)(atoi(xbt_dynar_get_as(tokens, cursor, char*))); + else + new_element->location.uconstant.value = (unsigned long int)(xbt_dynar_get_as(tokens, cursor, char*)[0] - '0');*/ + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strcmp(tok2, "DW_OP_consts:") == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_sconstant; + new_element->location.sconstant.bytes = 1; + new_element->location.sconstant.value = (long int)(atoi(xbt_dynar_get_as(tokens2, 1, char*))); + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strcmp(tok2, "DW_OP_const1u:") == 0 || + strcmp(tok2, "DW_OP_const2u:") == 0 || + strcmp(tok2, "DW_OP_const4u:") == 0 || + strcmp(tok2, "DW_OP_const8u:") == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_uconstant; + new_element->location.uconstant.bytes = tok2[11] - '0'; + new_element->location.uconstant.value = (unsigned long int)(atoi(xbt_dynar_get_as(tokens2, 1, char*))); + /*if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1) + new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, cursor, char*)); + else + new_element->location.constant.value = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0';*/ + xbt_dynar_push(loc->location.compose, &new_element); + }else if(strcmp(tok, "DW_OP_const1s") == 0 || + strcmp(tok, "DW_OP_const2s") == 0 || + strcmp(tok, "DW_OP_const4s") == 0 || + strcmp(tok, "DW_OP_const8s") == 0){ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_sconstant; + new_element->location.sconstant.bytes = tok2[11] - '0'; + new_element->location.sconstant.value = (long int)(atoi(xbt_dynar_get_as(tokens2, 1, char*))); + xbt_dynar_push(loc->location.compose, &new_element); + }else{ + dw_location_t new_element = xbt_new0(s_dw_location_t, 1); + new_element->type = e_dw_unsupported; + xbt_dynar_push(loc->location.compose, &new_element); + } + + cursor++; + xbt_dynar_free(&tokens2); + + } + + xbt_dynar_free(&tokens1); + + return loc; + + } - } -void print_local_variables(xbt_dynar_t list){ + +void print_local_variables(xbt_dict_t list){ - dw_frame_t frame; - dw_local_variable_t variable; dw_location_entry_t entry; dw_location_t location_entry; - unsigned int cursor = 0, cursor2 = 0, cursor3 = 0, cursor4 = 0; - - xbt_dynar_foreach(list, cursor, frame){ - fprintf(stderr, "Frame name : %s", frame->name); - fprintf(stderr, "Location type : %d\n", frame->location->type); - fprintf(stderr, "Variables : (%lu)\n", xbt_dynar_length(frame->variables)); - xbt_dynar_foreach(frame->variables, cursor2, variable){ - fprintf(stderr, "Name : %s", variable->name); - fprintf(stderr, "Location type : %d\n", variable->location->type); - switch(variable->location->type){ + unsigned int cursor3 = 0, cursor4 = 0; + xbt_dict_cursor_t cursor = 0, cursor2 = 0; + + char *frame_name, *variable_name; + dw_frame_t current_frame; + dw_local_variable_t current_variable; + + xbt_dict_foreach(list, cursor, frame_name, current_frame){ + fprintf(stderr, "Frame name : %s\n", current_frame->name); + fprintf(stderr, "Location type : %d\n", current_frame->frame_base->type); + xbt_dict_foreach((xbt_dict_t)current_frame->variables, cursor2, variable_name, current_variable){ + fprintf(stderr, "Name : %s\n", current_variable->name); + if(current_variable->location == NULL) + continue; + fprintf(stderr, "Location type : %d\n", current_variable->location->type); + switch(current_variable->location->type){ case e_dw_loclist : - xbt_dynar_foreach(variable->location->location.loclist, cursor3, entry){ - fprintf(stderr, "Lowpc : %p, Highpc : %p,", entry->lowpc, entry->highpc); + xbt_dynar_foreach(current_variable->location->location.loclist, cursor3, entry){ + fprintf(stderr, "Lowpc : %lx, Highpc : %lx,", entry->lowpc, entry->highpc); switch(entry->location->type){ case e_dw_register : fprintf(stderr, " Location : in register %d\n", entry->location->location.reg); @@ -1061,18 +1423,21 @@ void print_local_variables(xbt_dynar_t list){ fprintf(stderr, " %d) %d bytes from logical frame pointer\n", cursor4 + 1, location_entry->location.fbreg_op); break; case e_dw_deref: - fprintf(stderr, " %d) Pop the stack entry and treats it as an address (size of data %d)\n", cursor4 + 1, location_entry->location.deref_size); + fprintf(stderr, " %d) Pop the stack entry and treats it as an address (size of data %d)\n", cursor4 + 1, location_entry->location.deref_size); break; - case e_dw_arithmetic : + case e_dw_arithmetic : fprintf(stderr, "%d) arithmetic operation : %s\n", cursor4 + 1, location_entry->location.arithmetic); break; case e_dw_piece: fprintf(stderr, "%d) The %d byte(s) previous value\n", cursor4 + 1, location_entry->location.piece); break; - case e_dw_constant : - fprintf(stderr, "%d) Constant %d\n", cursor4 + 1, location_entry->location.constant.value); + case e_dw_uconstant : + fprintf(stderr, "%d) Unsigned constant %lu\n", cursor4 + 1, location_entry->location.uconstant.value); break; - default : + case e_dw_sconstant : + fprintf(stderr, "%d) Signed constant %lu\n", cursor4 + 1, location_entry->location.sconstant.value); + break; + default : fprintf(stderr, "%d) Location type not supported\n", cursor4 + 1); break; } @@ -1087,10 +1452,10 @@ void print_local_variables(xbt_dynar_t list){ case e_dw_compose: cursor4 = 0; fprintf(stderr, "Location :\n"); - xbt_dynar_foreach(variable->location->location.compose, cursor4, location_entry){ + xbt_dynar_foreach(current_variable->location->location.compose, cursor4, location_entry){ switch(location_entry->type){ case e_dw_register : - fprintf(stderr, " %d) in register %d\n", cursor4 + 1, location_entry->location.reg); + fprintf(stderr, " %d) in register %d\n", cursor4 + 1, location_entry->location.reg); break; case e_dw_bregister_op: fprintf(stderr, " %d) add %d to the value in register %d\n", cursor4 + 1, location_entry->location.breg_op.offset, location_entry->location.breg_op.reg); @@ -1102,18 +1467,21 @@ void print_local_variables(xbt_dynar_t list){ fprintf(stderr, " %d) %d bytes from logical frame pointer\n", cursor4 + 1, location_entry->location.fbreg_op); break; case e_dw_deref: - fprintf(stderr, " %d) Pop the stack entry and treats it as an address (size of data %d)\n", cursor4 + 1, location_entry->location.deref_size); + fprintf(stderr, " %d) Pop the stack entry and treats it as an address (size of data %d)\n", cursor4 + 1, location_entry->location.deref_size); break; - case e_dw_arithmetic : + case e_dw_arithmetic : fprintf(stderr, "%d) arithmetic operation : %s\n", cursor4 + 1, location_entry->location.arithmetic); break; case e_dw_piece: fprintf(stderr, "%d) The %d byte(s) previous value\n", cursor4 + 1, location_entry->location.piece); break; - case e_dw_constant : - fprintf(stderr, "%d) Constant %d\n", cursor4 + 1, location_entry->location.constant.value); + case e_dw_uconstant : + fprintf(stderr, "%d) Unsigned constant %lu\n", cursor4 + 1, location_entry->location.uconstant.value); + break; + case e_dw_sconstant : + fprintf(stderr, "%d) Signed constant %lu\n", cursor4 + 1, location_entry->location.sconstant.value); break; - default : + default : fprintf(stderr, "%d) Location type not supported\n", cursor4 + 1); break; } @@ -1127,171 +1495,3 @@ void print_local_variables(xbt_dynar_t list){ } } - -static e_dw_location_type get_location(char *expr, dw_location_t entry){ - - int cursor = 0; - char *tok = NULL, *tmp_tok = NULL; - - xbt_dynar_t tokens = xbt_str_split(expr, NULL); - xbt_dynar_remove_at(tokens, xbt_dynar_length(tokens) - 1, NULL); - - if(xbt_dynar_length(tokens) > 1){ - - entry->type = e_dw_compose; - entry->location.compose = xbt_dynar_new(sizeof(dw_location_t), NULL); - - while(cursor < xbt_dynar_length(tokens)){ - - tok = xbt_dynar_get_as(tokens, cursor, char*); - - if(strncmp(tok, "DW_OP_reg", 9) == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_register; - if(tok[9] == 'x'){ - new_element->location.reg = atoi(xbt_dynar_get_as(tokens, ++cursor, char*)); - }else{ - new_element->location.reg = atoi(strtok(tok, "DW_OP_reg")); - } - xbt_dynar_push(entry->location.compose, &new_element); - }else if(strcmp(tok, "DW_OP_fbreg") == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_fbregister_op; - new_element->location.fbreg_op = atoi(xbt_dynar_get_as(tokens, ++cursor, char*)); - xbt_dynar_push(entry->location.compose, &new_element); - }else if(strncmp(tok, "DW_OP_breg", 10) == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_bregister_op; - if(tok[10] == 'x'){ - new_element->location.breg_op.reg = atoi(xbt_dynar_get_as(tokens, ++cursor, char*)); - new_element->location.breg_op.offset = atoi(xbt_dynar_get_as(tokens, ++cursor, char*)); - }else{ - if(strchr(tok,'+') != NULL){ - tmp_tok = strtok(tok,"DW_OP_breg"); - new_element->location.breg_op.reg = atoi(strtok(tmp_tok,"+")); - new_element->location.breg_op.offset = atoi(strtok(NULL,"+")); - }else{ - new_element->location.breg_op.reg = atoi(strtok(tok, "DW_OP_breg")); - new_element->location.breg_op.offset = atoi(xbt_dynar_get_as(tokens, ++cursor, char*)); - } - } - xbt_dynar_push(entry->location.compose, &new_element); - }else if(strncmp(tok, "DW_OP_lit", 9) == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_lit; - new_element->location.lit = atoi(strtok(tok, "DW_OP_lit")); - xbt_dynar_push(entry->location.compose, &new_element); - }else if(strcmp(tok, "DW_OP_piece") == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_piece; - if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1) - new_element->location.piece = atoi(xbt_dynar_get_as(tokens, cursor, char*)); - else - new_element->location.piece = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0'; - xbt_dynar_push(entry->location.compose, &new_element); - - }else if(strcmp(tok, "DW_OP_abs") == 0 || - strcmp(tok, "DW_OP_and") == 0 || - strcmp(tok, "DW_OP_div") == 0 || - strcmp(tok, "DW_OP_minus") == 0 || - strcmp(tok, "DW_OP_mod") == 0 || - strcmp(tok, "DW_OP_mul") == 0 || - strcmp(tok, "DW_OP_neg") == 0 || - strcmp(tok, "DW_OP_not") == 0 || - strcmp(tok, "DW_OP_or") == 0 || - strcmp(tok, "DW_OP_plus") == 0 || - strcmp(tok, "DW_OP_plus_uconst") == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_arithmetic; - new_element->location.arithmetic = strdup(strtok(tok, "DW_OP_")); - xbt_dynar_push(entry->location.compose, &new_element); - }else if(strcmp(tok, "DW_OP_stack_value") == 0){ - cursor++; - }else if(strcmp(tok, "DW_OP_deref_size") == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_deref; - if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1) - new_element->location.deref_size = atoi(xbt_dynar_get_as(tokens, cursor, char*)); - else - new_element->location.deref_size = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0'; - xbt_dynar_push(entry->location.compose, &new_element); - }else if(strcmp(tok, "DW_OP_deref") == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_deref; - new_element->location.deref_size = sizeof(void *); - xbt_dynar_push(entry->location.compose, &new_element); - }else if(strcmp(tok, "DW_OP_constu") == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_constant; - new_element->location.constant.is_signed = 0; - new_element->location.constant.bytes = 1; - if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1) - new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, cursor, char*)); - else - new_element->location.constant.value = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0'; - xbt_dynar_push(entry->location.compose, &new_element); - }else if(strcmp(tok, "DW_OP_consts") == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_constant; - new_element->location.constant.is_signed = 1; - new_element->location.constant.bytes = 1; - new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, ++cursor, char*)); - xbt_dynar_push(entry->location.compose, &new_element); - }else if(strcmp(tok, "DW_OP_const1u") == 0 || - strcmp(tok, "DW_OP_const2u") == 0 || - strcmp(tok, "DW_OP_const4u") == 0 || - strcmp(tok, "DW_OP_const8u") == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_constant; - new_element->location.constant.is_signed = 0; - new_element->location.constant.bytes = tok[11] - '0'; - if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1) - new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, cursor, char*)); - else - new_element->location.constant.value = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0'; - xbt_dynar_push(entry->location.compose, &new_element); - }else if(strcmp(tok, "DW_OP_const1s") == 0 || - strcmp(tok, "DW_OP_const2s") == 0 || - strcmp(tok, "DW_OP_const4s") == 0 || - strcmp(tok, "DW_OP_const8s") == 0){ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_constant; - new_element->location.constant.is_signed = 1; - new_element->location.constant.bytes = tok[11] - '0'; - new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, ++cursor, char*)); - xbt_dynar_push(entry->location.compose, &new_element); - }else{ - dw_location_t new_element = xbt_new0(s_dw_location_t, 1); - new_element->type = e_dw_unsupported; - xbt_dynar_push(entry->location.compose, &new_element); - } - - cursor++; - - } - - xbt_dynar_free(&tokens); - - return e_dw_compose; - - }else{ - - if(strncmp(expr, "DW_OP_reg", 9) == 0){ - entry->type = e_dw_register; - entry->location.reg = atoi(strtok(expr,"DW_OP_reg")); - }else if(strncmp(expr, "DW_OP_breg", 10) == 0){ - entry->type = e_dw_bregister_op; - tok = strtok(expr, "+"); - entry->location.breg_op.offset = atoi(strtok(NULL, "+")); - entry->location.breg_op.reg = atoi(strtok(tok, "DW_OP_breg")); - }else{ - entry->type = e_dw_unsupported; - } - - xbt_dynar_free(&tokens); - - return entry->type; - - } - -} diff --git a/src/mc/mc_private.h b/src/mc/mc_private.h index 3172c25673..c84a1af964 100644 --- a/src/mc/mc_private.h +++ b/src/mc/mc_private.h @@ -275,9 +275,11 @@ typedef enum { e_dw_fbregister_op, e_dw_piece, e_dw_arithmetic, + e_dw_plus_uconst, e_dw_compose, e_dw_deref, - e_dw_constant, + e_dw_uconstant, + e_dw_sconstant, e_dw_unsupported } e_dw_location_type; @@ -290,34 +292,40 @@ typedef struct s_dw_location{ int reg; struct{ - int reg; + unsigned int reg; int offset; }breg_op; - unsigned lit; + unsigned int lit; int fbreg_op; int piece; - int deref_size; + unsigned short int deref_size; xbt_dynar_t compose; char *arithmetic; struct{ - int is_signed; int bytes; - int value; - }constant; + long unsigned int value; + }uconstant; + + struct{ + int bytes; + long signed int value; + }sconstant; + + unsigned int plus_uconst; }location; }s_dw_location_t, *dw_location_t; typedef struct s_dw_location_entry{ - void *lowpc; - void *highpc; + long lowpc; + long highpc; dw_location_t location; }s_dw_location_entry_t, *dw_location_entry_t; @@ -328,15 +336,30 @@ typedef struct s_dw_local_variable{ typedef struct s_dw_frame{ char *name; - dw_location_t location; - xbt_dynar_t variables; + void *low_pc; + void *high_pc; + dw_location_t frame_base; + xbt_dict_t variables; + unsigned long int start; + unsigned long int end; }s_dw_frame_t, *dw_frame_t; -/* FIXME : implement free functions for each strcuture */ +/* FIXME : implement free functions for each structure */ -extern xbt_dynar_t mc_binary_local_variables; +extern xbt_dict_t mc_local_variables; -void MC_get_binary_local_variables(void); -void print_local_variables(xbt_dynar_t list); +typedef struct s_variable_value{ + char *type; + + union{ + void *address; + long int res; + }value; +}s_variable_value_t, *variable_value_t; + +void MC_get_local_variables(const char *elf_file, xbt_dict_t location_list, xbt_dict_t *variables); +void print_local_variables(xbt_dict_t list); +char *get_libsimgrid_path(void); +xbt_dict_t MC_get_location_list(const char *elf_file); #endif -- 2.20.1