Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
model-checker : init MC for liveness in a separate function
[simgrid.git] / src / mc / mc_global.c
1 /* Copyright (c) 2008-2012 Da SimGrid Team. All rights reserved.            */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <sys/wait.h>
9 #include <sys/time.h>
10
11 #include "../surf/surf_private.h"
12 #include "../simix/smx_private.h"
13 #include "../xbt/mmalloc/mmprivate.h"
14 #include "xbt/fifo.h"
15 #include "mc_private.h"
16 #include "xbt/automaton.h"
17 #include "xbt/dict.h"
18
19 XBT_LOG_NEW_CATEGORY(mc, "All MC categories");
20 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_global, mc,
21                                 "Logging specific to MC (global)");
22
23 /* Configuration support */
24 e_mc_reduce_t mc_reduce_kind=e_mc_reduce_unset;
25
26
27 extern int _surf_init_status;
28 void _mc_cfg_cb_reduce(const char *name, int pos) {
29   if (_surf_init_status && !_surf_do_model_check) {
30     xbt_die("You are specifying a reduction strategy after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
31   }
32   char *val= xbt_cfg_get_string(_surf_cfg_set, name);
33   if (!strcasecmp(val,"none")) {
34     mc_reduce_kind = e_mc_reduce_none;
35   } else if (!strcasecmp(val,"dpor")) {
36     mc_reduce_kind = e_mc_reduce_dpor;
37   } else {
38     xbt_die("configuration option %s can only take 'none' or 'dpor' as a value",name);
39   }
40   xbt_cfg_set_int(_surf_cfg_set,"model-check",1);
41 }
42
43 void _mc_cfg_cb_checkpoint(const char *name, int pos) {
44   if (_surf_init_status && !_surf_do_model_check) {
45     xbt_die("You are specifying a checkpointing value after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
46   }
47   _surf_mc_checkpoint = xbt_cfg_get_int(_surf_cfg_set, name);
48   xbt_cfg_set_int(_surf_cfg_set,"model-check",1);
49 }
50 void _mc_cfg_cb_property(const char *name, int pos) {
51   if (_surf_init_status && !_surf_do_model_check) {
52     xbt_die("You are specifying a property after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
53   }
54   _surf_mc_property_file= xbt_cfg_get_string(_surf_cfg_set, name);
55   xbt_cfg_set_int(_surf_cfg_set,"model-check",1);
56 }
57
58
59 /* MC global data structures */
60
61 mc_state_t mc_current_state = NULL;
62 char mc_replay_mode = FALSE;
63 double *mc_time = NULL;
64 mc_snapshot_t initial_snapshot = NULL;
65 int raw_mem_set;
66
67 /* Safety */
68
69 xbt_fifo_t mc_stack_safety = NULL;
70 mc_stats_t mc_stats = NULL;
71
72 /* Liveness */
73
74 mc_stats_pair_t mc_stats_pair = NULL;
75 xbt_fifo_t mc_stack_liveness = NULL;
76 mc_snapshot_t initial_snapshot_liveness = NULL;
77 int compare;
78
79 /* Local */
80 xbt_dict_t mc_local_variables = NULL;
81
82 /* Ignore mechanism */
83 extern xbt_dynar_t mc_comparison_ignore;
84 extern xbt_dynar_t stacks_areas;
85
86 xbt_automaton_t _mc_property_automaton = NULL;
87
88 /* Static functions */
89
90 static void MC_assert_pair(int prop);
91 static dw_location_t get_location(xbt_dict_t location_list, char *expr);
92 static dw_frame_t get_frame_by_offset(xbt_dict_t all_variables, unsigned long int offset);
93
94 void MC_do_the_modelcheck_for_real() {
95   if (!_surf_mc_property_file || _surf_mc_property_file[0]=='\0') {
96     if (mc_reduce_kind==e_mc_reduce_unset)
97       mc_reduce_kind=e_mc_reduce_dpor;
98
99     XBT_INFO("Check a safety property");
100     MC_modelcheck();
101
102   } else  {
103
104     if (mc_reduce_kind==e_mc_reduce_unset)
105       mc_reduce_kind=e_mc_reduce_none;
106
107     XBT_INFO("Check the liveness property %s",_surf_mc_property_file);
108     MC_automaton_load(_surf_mc_property_file);
109     MC_modelcheck_liveness();
110   }
111 }
112
113 /**
114  *  \brief Initialize the model-checker data structures
115  */
116 void MC_init_safety(void)
117 {
118
119   raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
120
121   /* Check if MC is already initialized */
122   if (initial_snapshot)
123     return;
124
125   mc_time = xbt_new0(double, simix_process_maxpid);
126
127   /* Initialize the data structures that must be persistent across every
128      iteration of the model-checker (in RAW memory) */
129   
130   MC_SET_RAW_MEM;
131
132   /* Initialize statistics */
133   mc_stats = xbt_new0(s_mc_stats_t, 1);
134   mc_stats->state_size = 1;
135
136   /* Create exploration stack */
137   mc_stack_safety = xbt_fifo_new();
138
139   MC_UNSET_RAW_MEM;
140
141   MC_dpor_init();
142
143   MC_SET_RAW_MEM;
144   /* Save the initial state */
145   initial_snapshot = xbt_new0(s_mc_snapshot_t, 1);
146   MC_take_snapshot(initial_snapshot);
147   MC_UNSET_RAW_MEM;
148
149   if(raw_mem_set)
150     MC_SET_RAW_MEM;
151   else
152     MC_UNSET_RAW_MEM;
153   
154 }
155
156 void MC_compare(void){
157   compare = 1;
158 }
159
160
161 void MC_modelcheck(void)
162 {
163   MC_init_safety();
164   MC_dpor();
165   MC_exit();
166 }
167
168 void MC_init_liveness(){
169   
170   mc_time = xbt_new0(double, simix_process_maxpid);
171
172   /* mc_time refers to clock for each process -> ignore it for heap comparison */
173   int i;
174   for(i = 0; i<simix_process_maxpid; i++)
175     MC_ignore(&(mc_time[i]), sizeof(double));
176   
177   compare = 0;
178
179   /* Initialize the data structures that must be persistent across every
180      iteration of the model-checker (in RAW memory) */
181
182   MC_SET_RAW_MEM;
183
184   char *ls_path = get_libsimgrid_path(); 
185   
186   mc_local_variables = xbt_dict_new_homogeneous(NULL);
187
188   /* Get local variables in binary for state equality detection */
189   xbt_dict_t binary_location_list = MC_get_location_list(xbt_binary_name);
190   MC_get_local_variables(xbt_binary_name, binary_location_list, &mc_local_variables);
191
192   /* Get local variables in libsimgrid for state equality detection */
193   xbt_dict_t libsimgrid_location_list = MC_get_location_list(ls_path);
194   MC_get_local_variables(ls_path, libsimgrid_location_list, &mc_local_variables);
195
196   MC_UNSET_RAW_MEM;
197
198   MC_init_memory_map_info();
199
200   /* Get .plt section (start and end addresses) for data libsimgrid and data program comparison */
201   get_libsimgrid_plt_section();
202   get_binary_plt_section();
203
204 }
205
206 void MC_modelcheck_liveness(){
207
208   raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
209
210   MC_init_liveness();
211  
212   MC_SET_RAW_MEM;
213   
214   /* Initialize statistics */
215   mc_stats_pair = xbt_new0(s_mc_stats_pair_t, 1);
216
217   XBT_DEBUG("Creating stack");
218
219   /* Create exploration stack */
220   mc_stack_liveness = xbt_fifo_new();
221
222   MC_UNSET_RAW_MEM;
223
224   MC_ddfs_init();
225
226   /* We're done */
227   MC_print_statistics_pairs(mc_stats_pair);
228   xbt_free(mc_time);
229   MC_memory_exit();
230   exit(0);
231 }
232
233
234 void MC_exit(void)
235 {
236   MC_print_statistics(mc_stats);
237   xbt_free(mc_time);
238   MC_memory_exit();
239 }
240
241
242 int MC_random(int min, int max)
243 {
244   /*FIXME: return mc_current_state->executed_transition->random.value;*/
245   return 0;
246 }
247
248 /**
249  * \brief Schedules all the process that are ready to run
250  */
251 void MC_wait_for_requests(void)
252 {
253   smx_process_t process;
254   smx_simcall_t req;
255   unsigned int iter;
256
257   while (!xbt_dynar_is_empty(simix_global->process_to_run)) {
258     SIMIX_process_runall();
259     xbt_dynar_foreach(simix_global->process_that_ran, iter, process) {
260       req = &process->simcall;
261       if (req->call != SIMCALL_NONE && !MC_request_is_visible(req))
262         SIMIX_simcall_pre(req, 0);
263     }
264   }
265 }
266
267 int MC_deadlock_check()
268 {
269   int deadlock = FALSE;
270   smx_process_t process;
271   if(xbt_swag_size(simix_global->process_list)){
272     deadlock = TRUE;
273     xbt_swag_foreach(process, simix_global->process_list){
274       if(process->simcall.call != SIMCALL_NONE
275          && MC_request_is_enabled(&process->simcall)){
276         deadlock = FALSE;
277         break;
278       }
279     }
280   }
281   return deadlock;
282 }
283
284 /**
285  * \brief Re-executes from the state at position start all the transitions indicated by
286  *        a given model-checker stack.
287  * \param stack The stack with the transitions to execute.
288  * \param start Start index to begin the re-execution.
289  */
290 void MC_replay(xbt_fifo_t stack, int start)
291 {
292   raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
293
294   int value, i = 1;
295   char *req_str;
296   smx_simcall_t req = NULL, saved_req = NULL;
297   xbt_fifo_item_t item, start_item;
298   mc_state_t state;
299
300   XBT_DEBUG("**** Begin Replay ****");
301
302   if(start == -1){
303     /* Restore the initial state */
304     MC_restore_snapshot(initial_snapshot);
305     /* At the moment of taking the snapshot the raw heap was set, so restoring
306      * it will set it back again, we have to unset it to continue  */
307     MC_UNSET_RAW_MEM;
308   }
309
310   start_item = xbt_fifo_get_last_item(stack);
311   if(start != -1){
312     while (i != start){
313       start_item = xbt_fifo_get_prev_item(start_item);
314       i++;
315     }
316   }
317
318   /* Traverse the stack from the state at position start and re-execute the transitions */
319   for (item = start_item;
320        item != xbt_fifo_get_first_item(stack);
321        item = xbt_fifo_get_prev_item(item)) {
322
323     state = (mc_state_t) xbt_fifo_get_item_content(item);
324     saved_req = MC_state_get_executed_request(state, &value);
325    
326     if(saved_req){
327       /* because we got a copy of the executed request, we have to fetch the  
328          real one, pointed by the request field of the issuer process */
329       req = &saved_req->issuer->simcall;
330
331       /* Debug information */
332       if(XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)){
333         req_str = MC_request_to_string(req, value);
334         XBT_DEBUG("Replay: %s (%p)", req_str, state);
335         xbt_free(req_str);
336       }
337     }
338          
339     SIMIX_simcall_pre(req, value);
340     MC_wait_for_requests();
341          
342     /* Update statistics */
343     mc_stats->visited_states++;
344     mc_stats->executed_transitions++;
345   }
346   XBT_DEBUG("**** End Replay ****");
347
348   if(raw_mem_set)
349     MC_SET_RAW_MEM;
350   else
351     MC_UNSET_RAW_MEM;
352   
353
354 }
355
356 void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
357 {
358
359   raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
360
361   int value;
362   char *req_str;
363   smx_simcall_t req = NULL, saved_req = NULL;
364   xbt_fifo_item_t item;
365   mc_state_t state;
366   mc_pair_stateless_t pair;
367   int depth = 1;
368
369   XBT_DEBUG("**** Begin Replay ****");
370
371   /* Restore the initial state */
372   MC_restore_snapshot(initial_snapshot_liveness);
373   /* At the moment of taking the snapshot the raw heap was set, so restoring
374    * it will set it back again, we have to unset it to continue  */
375   MC_UNSET_RAW_MEM;
376
377   if(all_stack){
378
379     item = xbt_fifo_get_last_item(stack);
380
381     while(depth <= xbt_fifo_size(stack)){
382
383       pair = (mc_pair_stateless_t) xbt_fifo_get_item_content(item);
384       state = (mc_state_t) pair->graph_state;
385
386       if(pair->requests > 0){
387    
388         saved_req = MC_state_get_executed_request(state, &value);
389         //XBT_DEBUG("SavedReq->call %u", saved_req->call);
390       
391         if(saved_req != NULL){
392           /* because we got a copy of the executed request, we have to fetch the  
393              real one, pointed by the request field of the issuer process */
394           req = &saved_req->issuer->simcall;
395           //XBT_DEBUG("Req->call %u", req->call);
396   
397           /* Debug information */
398           if(XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)){
399             req_str = MC_request_to_string(req, value);
400             XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth, req_str, state);
401             xbt_free(req_str);
402           }
403   
404         }
405  
406         SIMIX_simcall_pre(req, value);
407         MC_wait_for_requests();
408       }
409
410       depth++;
411     
412       /* Update statistics */
413       mc_stats_pair->visited_pairs++;
414
415       item = xbt_fifo_get_prev_item(item);
416     }
417
418   }else{
419
420     /* Traverse the stack from the initial state and re-execute the transitions */
421     for (item = xbt_fifo_get_last_item(stack);
422          item != xbt_fifo_get_first_item(stack);
423          item = xbt_fifo_get_prev_item(item)) {
424
425       pair = (mc_pair_stateless_t) xbt_fifo_get_item_content(item);
426       state = (mc_state_t) pair->graph_state;
427
428       if(pair->requests > 0){
429    
430         saved_req = MC_state_get_executed_request(state, &value);
431         //XBT_DEBUG("SavedReq->call %u", saved_req->call);
432       
433         if(saved_req != NULL){
434           /* because we got a copy of the executed request, we have to fetch the  
435              real one, pointed by the request field of the issuer process */
436           req = &saved_req->issuer->simcall;
437           //XBT_DEBUG("Req->call %u", req->call);
438   
439           /* Debug information */
440           if(XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)){
441             req_str = MC_request_to_string(req, value);
442             XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth, req_str, state);
443             xbt_free(req_str);
444           }
445   
446         }
447  
448         SIMIX_simcall_pre(req, value);
449         MC_wait_for_requests();
450       }
451
452       depth++;
453     
454       /* Update statistics */
455       mc_stats_pair->visited_pairs++;
456     }
457   }  
458
459   XBT_DEBUG("**** End Replay ****");
460
461   if(raw_mem_set)
462     MC_SET_RAW_MEM;
463   else
464     MC_UNSET_RAW_MEM;
465   
466 }
467
468 /**
469  * \brief Dumps the contents of a model-checker's stack and shows the actual
470  *        execution trace
471  * \param stack The stack to dump
472  */
473 void MC_dump_stack_safety(xbt_fifo_t stack)
474 {
475   
476   raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
477
478   MC_show_stack_safety(stack);
479
480   if(!_surf_mc_checkpoint){
481
482     mc_state_t state;
483
484     MC_SET_RAW_MEM;
485     while ((state = (mc_state_t) xbt_fifo_pop(stack)) != NULL)
486       MC_state_delete(state);
487     MC_UNSET_RAW_MEM;
488
489   }
490
491   if(raw_mem_set)
492     MC_SET_RAW_MEM;
493   else
494     MC_UNSET_RAW_MEM;
495   
496 }
497
498
499 void MC_show_stack_safety(xbt_fifo_t stack)
500 {
501   int value;
502   mc_state_t state;
503   xbt_fifo_item_t item;
504   smx_simcall_t req;
505   char *req_str = NULL;
506   
507   for (item = xbt_fifo_get_last_item(stack);
508        (item ? (state = (mc_state_t) (xbt_fifo_get_item_content(item)))
509         : (NULL)); item = xbt_fifo_get_prev_item(item)) {
510     req = MC_state_get_executed_request(state, &value);
511     if(req){
512       req_str = MC_request_to_string(req, value);
513       XBT_INFO("%s", req_str);
514       xbt_free(req_str);
515     }
516   }
517 }
518
519 void MC_show_deadlock(smx_simcall_t req)
520 {
521   /*char *req_str = NULL;*/
522   XBT_INFO("**************************");
523   XBT_INFO("*** DEAD-LOCK DETECTED ***");
524   XBT_INFO("**************************");
525   XBT_INFO("Locked request:");
526   /*req_str = MC_request_to_string(req);
527     XBT_INFO("%s", req_str);
528     xbt_free(req_str);*/
529   XBT_INFO("Counter-example execution trace:");
530   MC_dump_stack_safety(mc_stack_safety);
531 }
532
533
534 void MC_show_stack_liveness(xbt_fifo_t stack){
535   int value;
536   mc_pair_stateless_t pair;
537   xbt_fifo_item_t item;
538   smx_simcall_t req;
539   char *req_str = NULL;
540   
541   for (item = xbt_fifo_get_last_item(stack);
542        (item ? (pair = (mc_pair_stateless_t) (xbt_fifo_get_item_content(item)))
543         : (NULL)); item = xbt_fifo_get_prev_item(item)) {
544     req = MC_state_get_executed_request(pair->graph_state, &value);
545     if(req){
546       if(pair->requests>0){
547         req_str = MC_request_to_string(req, value);
548         XBT_INFO("%s", req_str);
549         xbt_free(req_str);
550       }else{
551         XBT_INFO("End of system requests but evolution in B├╝chi automaton");
552       }
553     }
554   }
555 }
556
557 void MC_dump_stack_liveness(xbt_fifo_t stack){
558
559   raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
560
561   mc_pair_stateless_t pair;
562
563   MC_SET_RAW_MEM;
564   while ((pair = (mc_pair_stateless_t) xbt_fifo_pop(stack)) != NULL)
565     pair_stateless_free(pair);
566   MC_UNSET_RAW_MEM;
567
568   if(raw_mem_set)
569     MC_SET_RAW_MEM;
570   else
571     MC_UNSET_RAW_MEM;
572
573 }
574
575
576 void MC_print_statistics(mc_stats_t stats)
577 {
578   //XBT_INFO("State space size ~= %lu", stats->state_size);
579   XBT_INFO("Expanded states = %lu", stats->expanded_states);
580   XBT_INFO("Visited states = %lu", stats->visited_states);
581   XBT_INFO("Executed transitions = %lu", stats->executed_transitions);
582   XBT_INFO("Expanded / Visited = %lf",
583            (double) stats->visited_states / stats->expanded_states);
584   /*XBT_INFO("Exploration coverage = %lf",
585     (double)stats->expanded_states / stats->state_size); */
586 }
587
588 void MC_print_statistics_pairs(mc_stats_pair_t stats)
589 {
590   XBT_INFO("Expanded pairs = %lu", stats->expanded_pairs);
591   XBT_INFO("Visited pairs = %lu", stats->visited_pairs);
592   //XBT_INFO("Executed transitions = %lu", stats->executed_transitions);
593   XBT_INFO("Expanded / Visited = %lf",
594            (double) stats->visited_pairs / stats->expanded_pairs);
595   /*XBT_INFO("Exploration coverage = %lf",
596     (double)stats->expanded_states / stats->state_size); */
597 }
598
599 void MC_assert(int prop)
600 {
601   if (MC_is_active() && !prop){
602     XBT_INFO("**************************");
603     XBT_INFO("*** PROPERTY NOT VALID ***");
604     XBT_INFO("**************************");
605     XBT_INFO("Counter-example execution trace:");
606     MC_dump_stack_safety(mc_stack_safety);
607     MC_print_statistics(mc_stats);
608     xbt_abort();
609   }
610 }
611
612 static void MC_assert_pair(int prop){
613   if (MC_is_active() && !prop) {
614     XBT_INFO("**************************");
615     XBT_INFO("*** PROPERTY NOT VALID ***");
616     XBT_INFO("**************************");
617     //XBT_INFO("Counter-example execution trace:");
618     MC_show_stack_liveness(mc_stack_liveness);
619     //MC_dump_snapshot_stack(mc_snapshot_stack);
620     MC_print_statistics_pairs(mc_stats_pair);
621     xbt_abort();
622   }
623 }
624
625 void MC_process_clock_add(smx_process_t process, double amount)
626 {
627   mc_time[process->pid] += amount;
628 }
629
630 double MC_process_clock_get(smx_process_t process)
631 {
632   if(mc_time)
633     return mc_time[process->pid];
634   else
635     return 0;
636 }
637
638 void MC_automaton_load(const char *file){
639
640   raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
641
642   MC_SET_RAW_MEM;
643
644   if (_mc_property_automaton == NULL)
645     _mc_property_automaton = xbt_automaton_new();
646   
647   xbt_automaton_load(_mc_property_automaton,file);
648
649   MC_UNSET_RAW_MEM;
650
651   if(raw_mem_set)
652     MC_SET_RAW_MEM;
653   else
654     MC_UNSET_RAW_MEM;
655
656 }
657
658 void MC_automaton_new_propositional_symbol(const char* id, void* fct) {
659
660   raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
661
662   MC_SET_RAW_MEM;
663
664   if (_mc_property_automaton == NULL)
665     _mc_property_automaton = xbt_automaton_new();
666
667   xbt_new_propositional_symbol(_mc_property_automaton,id,fct);
668
669   MC_UNSET_RAW_MEM;
670
671   if(raw_mem_set)
672     MC_SET_RAW_MEM;
673   else
674     MC_UNSET_RAW_MEM;
675   
676 }
677
678 /************ MC_ignore ***********/ 
679
680 void MC_ignore(void *address, size_t size){
681
682   MC_SET_RAW_MEM;
683   
684   if(mc_comparison_ignore == NULL)
685     mc_comparison_ignore = xbt_dynar_new(sizeof(mc_ignore_region_t), NULL);
686
687   mc_ignore_region_t region = NULL;
688   region = xbt_new0(s_mc_ignore_region_t, 1);
689   region->address = address;
690   region->size = size;
691
692   if((address >= std_heap) && (address <= (void*)((char *)std_heap + STD_HEAP_SIZE))){
693
694     region->block = ((char*)address - (char*)((xbt_mheap_t)std_heap)->heapbase) / BLOCKSIZE + 1;
695     
696     if(((xbt_mheap_t)std_heap)->heapinfo[region->block].type == 0){
697       region->fragment = -1;
698     }else{
699       region->fragment = ((uintptr_t) (ADDR2UINT (address) % (BLOCKSIZE))) >> ((xbt_mheap_t)std_heap)->heapinfo[region->block].type;
700     }
701     
702   }
703
704   unsigned int cursor = 0;
705   mc_ignore_region_t current_region;
706   xbt_dynar_foreach(mc_comparison_ignore, cursor, current_region){
707     if(current_region->address > address)
708       break;
709   }
710
711   xbt_dynar_insert_at(mc_comparison_ignore, cursor, &region);
712
713   MC_UNSET_RAW_MEM;
714 }
715
716 void MC_new_stack_area(void *stack, char *name, void* context){
717
718   MC_SET_RAW_MEM;
719
720   if(stacks_areas == NULL)
721     stacks_areas = xbt_dynar_new(sizeof(stack_region_t), NULL);
722   
723   stack_region_t region = NULL;
724   region = xbt_new0(s_stack_region_t, 1);
725   region->address = stack;
726   region->process_name = strdup(name);
727   region->context = context;
728   xbt_dynar_push(stacks_areas, &region);
729   
730   MC_UNSET_RAW_MEM;
731 }
732
733 /************ DWARF ***********/
734
735 xbt_dict_t MC_get_location_list(const char *elf_file){
736
737   char *command = bprintf("objdump -Wo %s", elf_file);
738
739   FILE *fp = popen(command, "r");
740
741   if(fp == NULL)
742     perror("popen for objdump failed");
743
744   int debug = 0; /*Detect if the program has been compiled with -g */
745
746   xbt_dict_t location_list = xbt_dict_new_homogeneous(NULL);
747   char *line = NULL, *loc_expr = NULL;
748   ssize_t read;
749   size_t n = 0;
750   int cursor_remove;
751   xbt_dynar_t split = NULL;
752
753   while ((read = getline(&line, &n, fp)) != -1) {
754
755     /* Wipeout the new line character */
756     line[read - 1] = '\0';
757
758     xbt_str_trim(line, NULL);
759     
760     if(n == 0)
761       continue;
762
763     if(strlen(line) == 0)
764       continue;
765
766     if(debug == 0){
767
768       if(strncmp(line, elf_file, strlen(elf_file)) == 0)
769         continue;
770       
771       if(strncmp(line, "Contents", 8) == 0)
772         continue;
773
774       if(strncmp(line, "Offset", 6) == 0){
775         debug = 1;
776         continue;
777       }
778     }
779
780     if(debug == 0){
781       XBT_INFO("Your program must be compiled with -g");
782       xbt_abort();
783     }
784
785     xbt_dynar_t loclist = xbt_dynar_new(sizeof(dw_location_entry_t), NULL);
786
787     xbt_str_strip_spaces(line);
788     split = xbt_str_split(line, " ");
789
790     while(read != -1 && strcmp("<End", (char *)xbt_dynar_get_as(split, 1, char *)) != 0){
791       
792       dw_location_entry_t new_entry = xbt_new0(s_dw_location_entry_t, 1);
793       new_entry->lowpc = strtoul((char *)xbt_dynar_get_as(split, 1, char *), NULL, 16);
794       new_entry->highpc = strtoul((char *)xbt_dynar_get_as(split, 2, char *), NULL, 16);
795       
796       cursor_remove =0;
797       while(cursor_remove < 3){
798         xbt_dynar_remove_at(split, 0, NULL);
799         cursor_remove++;
800       }
801
802       loc_expr = xbt_str_join(split, " ");
803       xbt_str_ltrim(loc_expr, "(");
804       xbt_str_rtrim(loc_expr, ")");
805       new_entry->location = get_location(NULL, loc_expr);
806
807       xbt_dynar_push(loclist, &new_entry);
808
809       xbt_dynar_free(&split);
810       free(loc_expr);
811
812       read = getline(&line, &n, fp);
813       if(read != -1){
814         line[read - 1] = '\0';
815         xbt_str_strip_spaces(line);
816         split = xbt_str_split(line, " ");
817       }
818
819     }
820
821
822     char *key = bprintf("%d", (int)strtoul((char *)xbt_dynar_get_as(split, 0, char *), NULL, 16));
823     xbt_dict_set(location_list, key, loclist, NULL);
824     
825     xbt_dynar_free(&split);
826
827   }
828
829   free(line);
830   free(command);
831   pclose(fp);
832
833   return location_list;
834 }
835
836 char *get_libsimgrid_path(){
837
838   char *command = bprintf("ldd %s", xbt_binary_name);
839   
840   FILE *fp = popen(command, "r");
841   if(fp == NULL)
842     perror("popen for ldd failed");
843
844   char *line;
845   ssize_t read;
846   size_t n = 0;
847   xbt_dynar_t split;
848   
849   while((read = getline(&line, &n, fp)) != -1){
850   
851     if(n == 0)
852       continue;
853
854     /* Wipeout the new line character */
855     line[read - 1] = '\0';
856
857     xbt_str_strip_spaces(line);
858     xbt_str_ltrim(line, NULL);
859     split = xbt_str_split(line, " ");
860
861     if(strncmp((char *)xbt_dynar_get_as(split, 0, char *), "libsimgrid.so", 13) == 0){
862       free(line);
863       free(command);
864       pclose(fp);
865       return ((char *)xbt_dynar_get_as(split, 2, char *));
866     }
867
868     xbt_dynar_free(&split);
869     
870   }
871
872   free(line);
873   free(command);
874   pclose(fp);
875
876   return NULL;
877   
878 }
879
880 static dw_frame_t get_frame_by_offset(xbt_dict_t all_variables, unsigned long int offset){
881
882   xbt_dict_cursor_t cursor = NULL;
883   char *name;
884   dw_frame_t res;
885
886   xbt_dict_foreach(all_variables, cursor, name, res) {
887     if(offset >= res->start && offset < res->end)
888       return res;
889   }
890
891   return NULL;
892   
893 }
894
895 void MC_get_local_variables(const char *elf_file, xbt_dict_t location_list, xbt_dict_t *all_variables){
896
897   char *command = bprintf("objdump -Wi %s", elf_file);
898   
899   FILE *fp = popen(command, "r");
900
901   if(fp == NULL)
902     perror("popen for objdump failed");
903
904   char *line = NULL, *origin, *abstract_origin, *current_frame = NULL;
905   ssize_t read =0;
906   size_t n = 0;
907   int valid_variable = 1;
908   char *node_type = NULL, *location_type = NULL, *variable_name = NULL, *loc_expr = NULL;
909   xbt_dynar_t split = NULL, split2 = NULL;
910
911   xbt_dict_t variables_origin = xbt_dict_new_homogeneous(NULL);
912   xbt_dict_t subprograms_origin = xbt_dict_new_homogeneous(NULL);
913   char *subprogram_name = NULL, *subprogram_start = NULL, *subprogram_end = NULL;
914   int new_frame = 0, new_variable = 0;
915   dw_frame_t variable_frame, subroutine_frame = NULL;
916
917   read = getline(&line, &n, fp);
918
919   while (read != -1) {
920
921     if(n == 0){
922       read = getline(&line, &n, fp);
923       continue;
924     }
925  
926     /* Wipeout the new line character */
927     line[read - 1] = '\0';
928    
929     if(strlen(line) == 0){
930       read = getline(&line, &n, fp);
931       continue;
932     }
933
934     xbt_str_ltrim(line, NULL);
935     xbt_str_strip_spaces(line);
936     
937     if(line[0] != '<'){
938       read = getline(&line, &n, fp);
939       continue;
940     }
941     
942     xbt_dynar_free(&split);
943     split = xbt_str_split(line, " ");
944
945     /* Get node type */
946     node_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *);
947
948     if(strcmp(node_type, "(DW_TAG_subprogram)") == 0){ /* New frame */
949
950       dw_frame_t frame = NULL;
951
952       strtok(xbt_dynar_get_as(split, 0, char *), "<");
953       subprogram_start = strdup(strtok(NULL, "<"));
954       xbt_str_rtrim(subprogram_start, ">:");
955
956       read = getline(&line, &n, fp);
957    
958       while(read != -1){
959
960         if(n == 0){
961           read = getline(&line, &n, fp);
962           continue;
963         }
964
965         /* Wipeout the new line character */
966         line[read - 1] = '\0';
967         
968         if(strlen(line) == 0){
969           read = getline(&line, &n, fp);
970           continue;
971         }
972       
973         xbt_dynar_free(&split);
974         xbt_str_rtrim(line, NULL);
975         xbt_str_strip_spaces(line);
976         split = xbt_str_split(line, " ");
977           
978         node_type = xbt_dynar_get_as(split, 1, char *);
979
980         if(strncmp(node_type, "DW_AT_", 6) != 0)
981           break;
982
983         if(strcmp(node_type, "DW_AT_sibling") == 0){
984
985           subprogram_end = strdup(xbt_dynar_get_as(split, 3, char*));
986           xbt_str_ltrim(subprogram_end, "<0x");
987           xbt_str_rtrim(subprogram_end, ">");
988           
989         }else if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){ /* Frame already in dict */
990           
991           new_frame = 0;
992           abstract_origin = strdup(xbt_dynar_get_as(split, 2, char*));
993           xbt_str_ltrim(abstract_origin, "<0x");
994           xbt_str_rtrim(abstract_origin, ">");
995           subprogram_name = (char *)xbt_dict_get_or_null(subprograms_origin, abstract_origin);
996           frame = xbt_dict_get_or_null(*all_variables, subprogram_name); 
997
998         }else if(strcmp(node_type, "DW_AT_name") == 0){
999
1000           new_frame = 1;
1001           free(current_frame);
1002           frame = xbt_new0(s_dw_frame_t, 1);
1003           frame->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *)); 
1004           frame->variables = xbt_dict_new_homogeneous(NULL);
1005           frame->frame_base = xbt_new0(s_dw_location_t, 1); 
1006           current_frame = strdup(frame->name);
1007
1008           xbt_dict_set(subprograms_origin, subprogram_start, frame->name, NULL);
1009         
1010         }else if(strcmp(node_type, "DW_AT_frame_base") == 0){
1011
1012           location_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *);
1013
1014           if(strcmp(location_type, "list)") == 0){ /* Search location in location list */
1015
1016             frame->frame_base = get_location(location_list, xbt_dynar_get_as(split, 3, char *));
1017              
1018           }else{
1019                 
1020             xbt_str_strip_spaces(line);
1021             split2 = xbt_str_split(line, "(");
1022             xbt_dynar_remove_at(split2, 0, NULL);
1023             loc_expr = xbt_str_join(split2, " ");
1024             xbt_str_rtrim(loc_expr, ")");
1025             frame->frame_base = get_location(NULL, loc_expr);
1026             xbt_dynar_free(&split2);
1027
1028           }
1029  
1030         }else if(strcmp(node_type, "DW_AT_low_pc") == 0){
1031           
1032           if(frame != NULL)
1033             frame->low_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
1034
1035         }else if(strcmp(node_type, "DW_AT_high_pc") == 0){
1036
1037           if(frame != NULL)
1038             frame->high_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
1039
1040         }else if(strcmp(node_type, "DW_AT_MIPS_linkage_name:") == 0){
1041
1042           free(frame->name);
1043           free(current_frame);
1044           frame->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *));   
1045           current_frame = strdup(frame->name);
1046           xbt_dict_set(subprograms_origin, subprogram_start, frame->name, NULL);
1047
1048         }
1049
1050         read = getline(&line, &n, fp);
1051
1052       }
1053  
1054       if(new_frame == 1){
1055         frame->start = strtoul(subprogram_start, NULL, 16);
1056         if(subprogram_end != NULL)
1057           frame->end = strtoul(subprogram_end, NULL, 16);
1058         xbt_dict_set(*all_variables, frame->name, frame, NULL);
1059       }
1060
1061       free(subprogram_start);
1062       if(subprogram_end != NULL){
1063         free(subprogram_end);
1064         subprogram_end = NULL;
1065       }
1066         
1067
1068     }else if(strcmp(node_type, "(DW_TAG_variable)") == 0){ /* New variable */
1069
1070       dw_local_variable_t var = NULL;
1071       
1072       strtok(xbt_dynar_get_as(split, 0, char *), "<");
1073       origin = strdup(strtok(NULL, "<"));
1074       xbt_str_rtrim(origin, ">:");
1075       
1076       read = getline(&line, &n, fp);
1077       
1078       while(read != -1){
1079
1080         if(n == 0){
1081           read = getline(&line, &n, fp);
1082           continue;
1083         }
1084
1085         /* Wipeout the new line character */
1086         line[read - 1] = '\0'; 
1087
1088         if(strlen(line) == 0){
1089           read = getline(&line, &n, fp);
1090           continue;
1091         }
1092        
1093         xbt_dynar_free(&split);
1094         xbt_str_rtrim(line, NULL);
1095         xbt_str_strip_spaces(line);
1096         split = xbt_str_split(line, " ");
1097   
1098         node_type = xbt_dynar_get_as(split, 1, char *);
1099
1100         if(strncmp(node_type, "DW_AT_", 6) != 0)
1101           break;
1102
1103         if(strcmp(node_type, "DW_AT_name") == 0){
1104
1105           new_variable = 1;
1106           var = xbt_new0(s_dw_local_variable_t, 1);
1107           var->name = strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *));
1108
1109           xbt_dict_set(variables_origin, origin, var->name, NULL);
1110          
1111         }else if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){
1112
1113           new_variable = 0;
1114           abstract_origin = xbt_dynar_get_as(split, 2, char *);
1115           xbt_str_ltrim(abstract_origin, "<0x");
1116           xbt_str_rtrim(abstract_origin, ">");
1117           
1118           variable_name = (char *)xbt_dict_get_or_null(variables_origin, abstract_origin);
1119           variable_frame = get_frame_by_offset(*all_variables, strtoul(abstract_origin, NULL, 16));
1120           var = xbt_dict_get_or_null(variable_frame->variables, variable_name);   
1121
1122         }else if(strcmp(node_type, "DW_AT_location") == 0){
1123
1124           if(valid_variable == 1 && var != NULL){
1125
1126             var->location = xbt_new0(s_dw_location_t, 1);
1127
1128             location_type = xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *);
1129
1130             if(strcmp(location_type, "list)") == 0){ /* Search location in location list */
1131
1132               var->location = get_location(location_list, xbt_dynar_get_as(split, 3, char *));
1133              
1134             }else{
1135                 
1136               xbt_str_strip_spaces(line);
1137               split2 = xbt_str_split(line, "(");
1138               xbt_dynar_remove_at(split2, 0, NULL);
1139               loc_expr = xbt_str_join(split2, " ");
1140               xbt_str_rtrim(loc_expr, ")");
1141               var->location = get_location(NULL, loc_expr);
1142               xbt_dynar_free(&split2);
1143
1144             }
1145
1146           }
1147            
1148         }else if(strcmp(node_type, "DW_AT_external") == 0){
1149
1150           valid_variable = 0;
1151         
1152         }
1153
1154         read = getline(&line, &n, fp);
1155  
1156       }
1157
1158       if(new_variable == 1 && valid_variable == 1){
1159         
1160         variable_frame = xbt_dict_get_or_null(*all_variables, current_frame);
1161         xbt_dict_set(variable_frame->variables, var->name, var, NULL);
1162       }
1163
1164       valid_variable = 1;
1165       new_variable = 0;
1166
1167     }else if(strcmp(node_type, "(DW_TAG_inlined_subroutine)") == 0){
1168
1169       strtok(xbt_dynar_get_as(split, 0, char *), "<");
1170       origin = strdup(strtok(NULL, "<"));
1171       xbt_str_rtrim(origin, ">:");
1172
1173       read = getline(&line, &n, fp);
1174
1175       while(read != -1){
1176
1177         /* Wipeout the new line character */
1178         line[read - 1] = '\0'; 
1179
1180         if(n == 0){
1181           read = getline(&line, &n, fp);
1182           continue;
1183         }
1184
1185         if(strlen(line) == 0){
1186           read = getline(&line, &n, fp);
1187           continue;
1188         }
1189
1190         xbt_dynar_free(&split);
1191         xbt_str_rtrim(line, NULL);
1192         xbt_str_strip_spaces(line);
1193         split = xbt_str_split(line, " ");
1194         
1195         if(strncmp(xbt_dynar_get_as(split, 1, char *), "DW_AT_", 6) != 0)
1196           break;
1197           
1198         node_type = xbt_dynar_get_as(split, 1, char *);
1199
1200         if(strcmp(node_type, "DW_AT_abstract_origin:") == 0){
1201
1202           origin = xbt_dynar_get_as(split, 2, char *);
1203           xbt_str_ltrim(origin, "<0x");
1204           xbt_str_rtrim(origin, ">");
1205           
1206           subprogram_name = (char *)xbt_dict_get_or_null(subprograms_origin, origin);
1207           subroutine_frame = xbt_dict_get_or_null(*all_variables, subprogram_name);
1208         
1209         }else if(strcmp(node_type, "DW_AT_low_pc") == 0){
1210
1211           subroutine_frame->low_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
1212
1213         }else if(strcmp(node_type, "DW_AT_high_pc") == 0){
1214
1215           subroutine_frame->high_pc = (void *)strtoul(xbt_dynar_get_as(split, 3, char *), NULL, 16);
1216         }
1217
1218         read = getline(&line, &n, fp);
1219       
1220       }
1221
1222     }else{
1223
1224       read = getline(&line, &n, fp);
1225
1226     }
1227
1228   }
1229   
1230   xbt_dynar_free(&split);
1231   free(line);
1232   free(command);
1233   pclose(fp);
1234   
1235 }
1236
1237 static dw_location_t get_location(xbt_dict_t location_list, char *expr){
1238
1239   dw_location_t loc = xbt_new0(s_dw_location_t, 1);
1240
1241   if(location_list != NULL){
1242     
1243     char *key = bprintf("%d", (int)strtoul(expr, NULL, 16));
1244     loc->type = e_dw_loclist;
1245     loc->location.loclist =  (xbt_dynar_t)xbt_dict_get_or_null(location_list, key);
1246     if(loc == NULL)
1247       XBT_INFO("Key not found in loclist");
1248     return loc;
1249
1250   }else{
1251
1252     int cursor = 0;
1253     char *tok = NULL, *tok2 = NULL; 
1254     
1255     xbt_dynar_t tokens1 = xbt_str_split(expr, ";");
1256     xbt_dynar_t tokens2;
1257
1258     loc->type = e_dw_compose;
1259     loc->location.compose = xbt_dynar_new(sizeof(dw_location_t), NULL);
1260
1261     while(cursor < xbt_dynar_length(tokens1)){
1262
1263       tok = xbt_dynar_get_as(tokens1, cursor, char*);
1264       tokens2 = xbt_str_split(tok, " ");
1265       tok2 = xbt_dynar_get_as(tokens2, 0, char*);
1266       
1267       if(strncmp(tok2, "DW_OP_reg", 9) == 0){
1268         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1269         new_element->type = e_dw_register;
1270         new_element->location.reg = atoi(strtok(tok2, "DW_OP_reg"));
1271         xbt_dynar_push(loc->location.compose, &new_element);     
1272       }else if(strcmp(tok2, "DW_OP_fbreg:") == 0){
1273         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1274         new_element->type = e_dw_fbregister_op;
1275         new_element->location.fbreg_op = atoi(xbt_dynar_get_as(tokens2, 1, char*));
1276         xbt_dynar_push(loc->location.compose, &new_element);
1277       }else if(strncmp(tok2, "DW_OP_breg", 10) == 0){
1278         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1279         new_element->type = e_dw_bregister_op;
1280         new_element->location.breg_op.reg = atoi(strtok(tok2, "DW_OP_breg"));
1281         new_element->location.breg_op.offset = atoi(xbt_dynar_get_as(tokens2, 2, char*));
1282         xbt_dynar_push(loc->location.compose, &new_element);
1283       }else if(strncmp(tok2, "DW_OP_lit", 9) == 0){
1284         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1285         new_element->type = e_dw_lit;
1286         new_element->location.lit = atoi(strtok(tok2, "DW_OP_lit"));
1287         xbt_dynar_push(loc->location.compose, &new_element);
1288       }else if(strcmp(tok2, "DW_OP_piece:") == 0){
1289         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1290         new_element->type = e_dw_piece;
1291         new_element->location.piece = atoi(xbt_dynar_get_as(tokens2, 1, char*));
1292         /*if(strlen(xbt_dynar_get_as(tokens2, 1, char*)) > 1)
1293           new_element->location.piece = atoi(xbt_dynar_get_as(tokens2, 1, char*));
1294         else
1295         new_element->location.piece = xbt_dynar_get_as(tokens2, 1, char*)[0] - '0';*/
1296         xbt_dynar_push(loc->location.compose, &new_element);
1297       }else if(strcmp(tok2, "DW_OP_plus_uconst:") == 0){
1298         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1299         new_element->type = e_dw_plus_uconst;
1300         new_element->location.plus_uconst = atoi(xbt_dynar_get_as(tokens2, 1, char *));
1301         xbt_dynar_push(loc->location.compose, &new_element);
1302       }else if(strcmp(tok, "DW_OP_abs") == 0 || 
1303                strcmp(tok, "DW_OP_and") == 0 ||
1304                strcmp(tok, "DW_OP_div") == 0 ||
1305                strcmp(tok, "DW_OP_minus") == 0 ||
1306                strcmp(tok, "DW_OP_mod") == 0 ||
1307                strcmp(tok, "DW_OP_mul") == 0 ||
1308                strcmp(tok, "DW_OP_neg") == 0 ||
1309                strcmp(tok, "DW_OP_not") == 0 ||
1310                strcmp(tok, "DW_OP_or") == 0 ||
1311                strcmp(tok, "DW_OP_plus") == 0){               
1312         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1313         new_element->type = e_dw_arithmetic;
1314         new_element->location.arithmetic = strdup(strtok(tok2, "DW_OP_"));
1315         xbt_dynar_push(loc->location.compose, &new_element);
1316       }else if(strcmp(tok, "DW_OP_stack_value") == 0){
1317       }else if(strcmp(tok2, "DW_OP_deref_size:") == 0){
1318         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1319         new_element->type = e_dw_deref;
1320         new_element->location.deref_size = (unsigned int short) atoi(xbt_dynar_get_as(tokens2, 1, char*));
1321         /*if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1)
1322           new_element->location.deref_size = atoi(xbt_dynar_get_as(tokens, cursor, char*));
1323         else
1324         new_element->location.deref_size = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0';*/
1325         xbt_dynar_push(loc->location.compose, &new_element);
1326       }else if(strcmp(tok, "DW_OP_deref") == 0){
1327         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1328         new_element->type = e_dw_deref;
1329         new_element->location.deref_size = sizeof(void *);
1330         xbt_dynar_push(loc->location.compose, &new_element);
1331       }else if(strcmp(tok2, "DW_OP_constu:") == 0){
1332         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1333         new_element->type = e_dw_uconstant;
1334         new_element->location.uconstant.bytes = 1;
1335         new_element->location.uconstant.value = (unsigned long int)(atoi(xbt_dynar_get_as(tokens2, 1, char*)));
1336         /*if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1)
1337           new_element->location.uconstant.value = (unsigned long int)(atoi(xbt_dynar_get_as(tokens, cursor, char*)));
1338         else
1339         new_element->location.uconstant.value = (unsigned long int)(xbt_dynar_get_as(tokens, cursor, char*)[0] - '0');*/
1340         xbt_dynar_push(loc->location.compose, &new_element);
1341       }else if(strcmp(tok2, "DW_OP_consts:") == 0){
1342         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1343         new_element->type = e_dw_sconstant;
1344         new_element->location.sconstant.bytes = 1;
1345         new_element->location.sconstant.value = (long int)(atoi(xbt_dynar_get_as(tokens2, 1, char*)));
1346         xbt_dynar_push(loc->location.compose, &new_element);
1347       }else if(strcmp(tok2, "DW_OP_const1u:") == 0 ||
1348                strcmp(tok2, "DW_OP_const2u:") == 0 ||
1349                strcmp(tok2, "DW_OP_const4u:") == 0 ||
1350                strcmp(tok2, "DW_OP_const8u:") == 0){
1351         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1352         new_element->type = e_dw_uconstant;
1353         new_element->location.uconstant.bytes = tok2[11] - '0';
1354         new_element->location.uconstant.value = (unsigned long int)(atoi(xbt_dynar_get_as(tokens2, 1, char*)));
1355         /*if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1)
1356           new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, cursor, char*));
1357         else
1358         new_element->location.constant.value = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0';*/
1359         xbt_dynar_push(loc->location.compose, &new_element);
1360       }else if(strcmp(tok, "DW_OP_const1s") == 0 ||
1361                strcmp(tok, "DW_OP_const2s") == 0 ||
1362                strcmp(tok, "DW_OP_const4s") == 0 ||
1363                strcmp(tok, "DW_OP_const8s") == 0){
1364         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1365         new_element->type = e_dw_sconstant;
1366         new_element->location.sconstant.bytes = tok2[11] - '0';
1367         new_element->location.sconstant.value = (long int)(atoi(xbt_dynar_get_as(tokens2, 1, char*)));
1368         xbt_dynar_push(loc->location.compose, &new_element);
1369       }else{
1370         dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
1371         new_element->type = e_dw_unsupported;
1372         xbt_dynar_push(loc->location.compose, &new_element);
1373       }
1374
1375       cursor++;
1376       xbt_dynar_free(&tokens2);
1377
1378     }
1379     
1380     xbt_dynar_free(&tokens1);
1381
1382     return loc;
1383     
1384   }
1385
1386 }
1387
1388
1389 void print_local_variables(xbt_dict_t list){
1390   
1391   dw_location_entry_t entry;
1392   dw_location_t location_entry;
1393   unsigned int cursor3 = 0, cursor4 = 0;
1394   xbt_dict_cursor_t cursor = 0, cursor2 = 0;
1395
1396   char *frame_name, *variable_name;
1397   dw_frame_t current_frame;
1398   dw_local_variable_t current_variable;
1399
1400   xbt_dict_foreach(list, cursor, frame_name, current_frame){ 
1401     fprintf(stderr, "Frame name : %s\n", current_frame->name);
1402     fprintf(stderr, "Location type : %d\n", current_frame->frame_base->type);
1403     xbt_dict_foreach((xbt_dict_t)current_frame->variables, cursor2, variable_name, current_variable){
1404       fprintf(stderr, "Name : %s\n", current_variable->name);
1405       if(current_variable->location == NULL)
1406         continue;
1407       fprintf(stderr, "Location type : %d\n", current_variable->location->type);
1408       switch(current_variable->location->type){
1409       case e_dw_loclist :
1410         xbt_dynar_foreach(current_variable->location->location.loclist, cursor3, entry){
1411           fprintf(stderr, "Lowpc : %lx, Highpc : %lx,", entry->lowpc, entry->highpc);
1412           switch(entry->location->type){
1413           case e_dw_register :
1414             fprintf(stderr, " Location : in register %d\n", entry->location->location.reg);
1415             break;
1416           case e_dw_bregister_op:
1417             fprintf(stderr, " Location : Add %d to the value in register %d\n", entry->location->location.breg_op.offset, entry->location->location.breg_op.reg);
1418             break;
1419           case e_dw_lit:
1420             fprintf(stderr, "Value already kwnown : %d\n", entry->location->location.lit);
1421             break;
1422           case e_dw_fbregister_op:
1423             fprintf(stderr, " Location : %d bytes from logical frame pointer\n", entry->location->location.fbreg_op);
1424             break;
1425           case e_dw_compose:
1426             fprintf(stderr, " Location :\n");
1427             xbt_dynar_foreach(entry->location->location.compose, cursor4, location_entry){
1428               switch(location_entry->type){
1429               case e_dw_register :
1430                 fprintf(stderr, " %d) in register %d\n", cursor4 + 1, location_entry->location.reg);
1431                 break;
1432               case e_dw_bregister_op:
1433                 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);
1434                 break;
1435               case e_dw_lit:
1436                 fprintf(stderr, "%d) Value already kwnown : %d\n", cursor4 + 1, location_entry->location.lit);
1437                 break;
1438               case e_dw_fbregister_op:
1439                 fprintf(stderr, " %d) %d bytes from logical frame pointer\n", cursor4 + 1, location_entry->location.fbreg_op);
1440                 break;
1441               case e_dw_deref:
1442                 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);
1443                 break;
1444               case e_dw_arithmetic :
1445                 fprintf(stderr, "%d) arithmetic operation : %s\n", cursor4 + 1, location_entry->location.arithmetic);
1446                 break;
1447               case e_dw_piece:
1448                 fprintf(stderr, "%d) The %d byte(s) previous value\n", cursor4 + 1, location_entry->location.piece);
1449                 break;
1450               case e_dw_uconstant :
1451                 fprintf(stderr, "%d) Unsigned constant %lu\n", cursor4 + 1, location_entry->location.uconstant.value);
1452                 break;
1453               case e_dw_sconstant :
1454                 fprintf(stderr, "%d) Signed constant %lu\n", cursor4 + 1, location_entry->location.sconstant.value);
1455                 break;
1456               default :
1457                 fprintf(stderr, "%d) Location type not supported\n", cursor4 + 1);
1458                 break;
1459               }
1460             }
1461             break;
1462           default:
1463             fprintf(stderr, "Location type not supported\n");
1464             break;
1465           }
1466         }
1467         break;
1468       case e_dw_compose:
1469         cursor4 = 0;
1470         fprintf(stderr, "Location :\n");
1471         xbt_dynar_foreach(current_variable->location->location.compose, cursor4, location_entry){
1472           switch(location_entry->type){
1473           case e_dw_register :
1474             fprintf(stderr, " %d) in register %d\n", cursor4 + 1, location_entry->location.reg);
1475             break;
1476           case e_dw_bregister_op:
1477             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);
1478             break;
1479           case e_dw_lit:
1480             fprintf(stderr, "%d) Value already kwnown : %d\n", cursor4 + 1, location_entry->location.lit);
1481             break;
1482           case e_dw_fbregister_op:
1483             fprintf(stderr, " %d) %d bytes from logical frame pointer\n", cursor4 + 1, location_entry->location.fbreg_op);
1484             break;
1485           case e_dw_deref:
1486             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);
1487             break;
1488           case e_dw_arithmetic :
1489             fprintf(stderr, "%d) arithmetic operation : %s\n", cursor4 + 1, location_entry->location.arithmetic);
1490             break;
1491           case e_dw_piece:
1492             fprintf(stderr, "%d) The %d byte(s) previous value\n", cursor4 + 1, location_entry->location.piece);
1493             break;
1494           case e_dw_uconstant :
1495             fprintf(stderr, "%d) Unsigned constant %lu\n", cursor4 + 1, location_entry->location.uconstant.value);
1496             break;
1497           case e_dw_sconstant :
1498             fprintf(stderr, "%d) Signed constant %lu\n", cursor4 + 1, location_entry->location.sconstant.value);
1499             break;
1500           default :
1501             fprintf(stderr, "%d) Location type not supported\n", cursor4 + 1);
1502             break;
1503           }
1504         }
1505         break;
1506       default :
1507         fprintf(stderr, "Location type not supported\n");
1508         break;
1509       }
1510     }
1511   }
1512
1513 }