#define _GNU_SOURCE
#include <string.h>
+#include <link.h>
#include "mc_private.h"
#include "xbt/module.h"
#include "../simix/smx_private.h"
#include <libunwind.h>
+#include <libelf.h>
+
+#include "mc_private.h"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc,
"Logging specific to mc_checkpoint");
char *libsimgrid_path;
static void MC_find_object_address(memory_map_t maps, mc_object_info_t result);
-static void MC_get_plt_section(mc_object_info_t info);
/************************************ Free functions **************************************/
/*****************************************************************************************/
else if ((reg.prot & PROT_WRITE) && !memcmp(maps->regions[i].pathname, "[stack]", 7)){
maestro_stack_start = reg.start_addr;
maestro_stack_end = reg.end_addr;
- }else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC) && !memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
+ } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC) && !memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
if(libsimgrid_path == NULL)
libsimgrid_path = strdup(maps->regions[i].pathname);
}
result->start_data = NULL;
result->start_text = NULL;
MC_find_object_address(maps, result);
- MC_get_plt_section(result);
+ result->location_list = MC_dwarf_get_location_list(result->file_name);
MC_dwarf_get_variables(result);
return result;
}
/** \brief Fills the position of the .bss and .data sections. */
static void MC_find_object_address(memory_map_t maps, mc_object_info_t result) {
+
unsigned int i = 0;
s_map_region_t reg;
- const char* name = result->file_name;
- int len = strlen(basename(result->file_name));
+ const char* name = basename(result->file_name);
while (i < maps->mapsize) {
reg = maps->regions[i];
- if (maps->regions[i].pathname == NULL || memcmp(basename(maps->regions[i].pathname), basename(name), len)){
+ if (maps->regions[i].pathname == NULL || strcmp(basename(maps->regions[i].pathname), name)) {
// Nothing to do
}
else if ((reg.prot & PROT_WRITE)){
result->start_data = reg.start_addr;
- i++;
- reg = maps->regions[i];
- }else if (reg.prot & PROT_READ) {
+ } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)){
result->start_text = reg.start_addr;
}
i++;
xbt_assert(result->file_name);
xbt_assert(result->start_data);
xbt_assert(result->start_text);
-
- MC_get_plt_section(result);
-}
-
-/** \brief Fills the position of the .plt and .got.plt sections. */
-static void MC_get_plt_section(mc_object_info_t info){
-
- FILE *fp;
- char *line = NULL; /* Temporal storage for each line that is readed */
- ssize_t read; /* Number of bytes readed */
- size_t n = 0; /* Amount of bytes to read by xbt_getline */
-
- char *lfields[7];
- int i, plt_found = 0;
- unsigned long int size, offset;
-
- char *command = bprintf("LANG=C objdump --section-headers %s", info->file_name);
-
- fp = popen(command, "r");
-
- if(fp == NULL){
- perror("popen failed");
- xbt_abort();
- }
-
- while ((read = xbt_getline(&line, &n, fp)) != -1 && plt_found != 2) {
-
- if(n == 0)
- continue;
-
- /* Wipeout the new line character */
- line[read - 1] = '\0';
-
- lfields[0] = strtok(line, " ");
-
- if(lfields[0] == NULL)
- continue;
-
- if(strcmp(lfields[0], "Sections:") == 0 || strcmp(lfields[0], "Idx") == 0 || strncmp(lfields[0], info->file_name, strlen(info->file_name)) == 0)
- continue;
-
- for (i = 1; i < 7 && lfields[i - 1] != NULL; i++) {
- lfields[i] = strtok(NULL, " ");
- }
-
- if(i>=6){
- if(strcmp(lfields[1], ".plt") == 0){
- size = strtoul(lfields[2], NULL, 16);
- offset = strtoul(lfields[5], NULL, 16);
- info->start_plt = (char *) info->start_text + offset;
- info->end_plt = (char *) info->start_plt + size;
- plt_found++;
- }else if(strcmp(lfields[1], ".got.plt") == 0){
- size = strtoul(lfields[2], NULL, 16);
- offset = strtoul(lfields[5], NULL, 16);
- info->start_got_plt = (char *) info->start_text + offset;
- info->end_got_plt = (char *) info->start_plt + size;
- plt_found++;
- }
-
- }
-
- }
-
- xbt_free(command);
- xbt_free(line);
- pclose(fp);
-
}
/************************************* Take Snapshot ************************************/
}
+
+
static xbt_dynar_t MC_get_local_variables_values(void *stack_context){
unw_cursor_t c;
unsigned int cursor = 0;
dw_variable_t current_variable;
dw_location_entry_t entry = NULL;
- dw_location_t location_entry = NULL;
- unw_word_t res;
int frame_found = 0, region_type;
void *frame_pointer_address = NULL;
- long true_ip, value;
+ long true_ip;
int stop = 0;
xbt_dynar_t variables = xbt_dynar_new(sizeof(local_variable_t), local_variable_free_voidp);
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:
- if(xbt_dynar_length(entry->location->location.compose) > 1){
- frame_pointer_address = NULL; /* TODO : location list with optimizations enabled */
- }else{
- location_entry = xbt_dynar_get_as(entry->location->location.compose, 0, dw_location_t);
- switch(location_entry->type){
- case e_dw_register:
- unw_get_reg(&c, location_entry->location.reg, &res);
- frame_pointer_address = (void*)(long)res;
- break;
- case e_dw_bregister_op:
- unw_get_reg(&c, location_entry->location.breg_op.reg, &res);
- frame_pointer_address = (void*)((long)res + location_entry->location.breg_op.offset);
- break;
- default:
- frame_pointer_address = NULL; /* FIXME : implement other cases (with optimizations enabled) */
- break;
- }
- }
- break;
- default:
- frame_pointer_address = NULL; /* FIXME : implement other cases (with optimizations enabled) */
- break;
- }
+ frame_pointer_address = (void*) MC_dwarf_resolve_location(&c, entry->location, NULL);
}
cursor++;
}
new_var->region= region_type;
if(current_variable->address.location != NULL){
- switch(current_variable->address.location->type){
- case e_dw_compose:
- if(xbt_dynar_length(current_variable->address.location->location.compose) > 1){
- /* TODO : location list with optimizations enabled */
- }else{
- location_entry = xbt_dynar_get_as(current_variable->address.location->location.compose, 0, dw_location_t);
-
- switch(location_entry->type){
- case e_dw_register:
- unw_get_reg(&c, location_entry->location.reg, &res);
- value = (long)res;
- break;
- case e_dw_bregister_op:
- unw_get_reg(&c, location_entry->location.breg_op.reg, &res);
- value = (long)res + location_entry->location.breg_op.offset;
- break;
- case e_dw_fbregister_op:
- if(frame_pointer_address != NULL)
- value = (long)((char *)frame_pointer_address + location_entry->location.fbreg_op);
- else
- value = 0;
- break;
- default:
- value = 0; /* FIXME : implement other cases (with optimizations enabled)*/
- break;
- }
-
- if(value)
- new_var->address = (void *)value;
- else
- new_var->address = NULL;
- }
- break;
- default :
- break;
- }
+ new_var->address = (void*) MC_dwarf_resolve_location(&c, current_variable->address.location, frame_pointer_address);
}
xbt_dynar_push(variables, &new_var);