// XXX: figure out how to use simics list/string attributes static set_error_t set_ls_arbiter_choice_attribute( void *arg, conf_object_t *obj, attr_value_t *val, attr_value_t *idx) { int tid = SIM_attr_integer(*val); /* XXX: dum hack */ if (tid == -42) { return Sim_Set_Not_Writable; } else { arbiter_append_choice(&((struct ls_state *)obj)->arbiter, tid); return Sim_Set_Ok; } }
static set_error_t set_ls_decision_trace_attribute( void *arg, conf_object_t *obj, attr_value_t *val, attr_value_t *idx) { int value = SIM_attr_integer(*val); if (value != 0x15410de0u) { if (value == 0) { DUMP_DECISION_INFO_QUIET((struct ls_state *)obj); } else { DUMP_DECISION_INFO((struct ls_state *)obj); } } return Sim_Set_Ok; }
/* New interface. Returns malloced strings through output parameters, * which caller must free result strings if returnval is true */ bool symtable_lookup(unsigned int eip, char **func, char **file, int *line) { conf_object_t *table = get_symtable(); if (table == NULL) { return false; } attr_value_t idx = SIM_make_attr_integer(eip); attr_value_t result = SIM_get_attribute_idx(table, "source_at", &idx); if (!SIM_attr_is_list(result)) { SIM_free_attribute(idx); return false; } assert(SIM_attr_list_size(result) >= 3); /* Copy out the function name and line number. However, need to * do some checks on the filename before copying it out as well. */ if (testing_userspace() && eip == GUEST_CONTEXT_SWITCH_ENTER) { *func = MM_XSTRDUP("[context switch]"); #ifdef GUEST_HLT_EXIT } else if (testing_userspace() && eip == GUEST_HLT_EXIT) { *func = MM_XSTRDUP("[kernel idle]"); #endif } else { *func = MM_XSTRDUP(SIM_attr_string(SIM_attr_list_item(result, 2))); } const char *maybe_file = SIM_attr_string(SIM_attr_list_item(result, 0)); *line = SIM_attr_integer(SIM_attr_list_item(result, 1)); /* A hack to make the filenames shorter */ if (strstr(maybe_file, LIKELY_DIR) != NULL) { maybe_file = strstr(maybe_file, LIKELY_DIR) + strlen(LIKELY_DIR); } /* The symbol table will claim that unknown assembly comes from * 410kern/boot/head.S. Print an 'unknown' message instead. */ if (strncmp(maybe_file, UNKNOWN_FILE, strlen(maybe_file)) == 0) { *file = NULL; } else { *file = MM_XSTRDUP(maybe_file); } SIM_free_attribute(result); SIM_free_attribute(idx); return true; }
/* Finds how many instructions away the given eip is from the start of its * containing function. */ bool function_eip_offset(unsigned int eip, unsigned int *offset) { conf_object_t *table = get_symtable(); if (table == NULL) { return false; } attr_value_t idx = SIM_make_attr_integer(eip); attr_value_t result = SIM_get_attribute_idx(table, "source_at", &idx); if (!SIM_attr_is_list(result)) { SIM_free_attribute(idx); return false; } assert(SIM_attr_list_size(result) >= 3); attr_value_t name = SIM_attr_list_item(result, 2); attr_value_t func = SIM_get_attribute_idx(table, "symbol_value", &name); *offset = eip - SIM_attr_integer(func); SIM_free_attribute(result); SIM_free_attribute(idx); return true; }
unsigned int symtable_lookup_data(char *buf, unsigned int maxlen, unsigned int addr) { conf_object_t *table = get_symtable(); if (table == NULL) { return scnprintf(buf, maxlen, GLOBAL_COLOUR "global0x%.8x" COLOUR_DEFAULT, addr); } attr_value_t idx = SIM_make_attr_integer(addr); attr_value_t result = SIM_get_attribute_idx(table, "data_at", &idx); if (!SIM_attr_is_list(result)) { SIM_free_attribute(idx); if (KERNEL_MEMORY(addr)) { return scnprintf(buf, maxlen, "<user global0x%x>", addr); } else { return scnprintf(buf, maxlen, GLOBAL_COLOUR "<kernel global0x%.8x>" COLOUR_DEFAULT, addr); } } assert(SIM_attr_list_size(result) >= 4); const char *globalname = SIM_attr_string(SIM_attr_list_item(result, 1)); const char *typename = SIM_attr_string(SIM_attr_list_item(result, 2)); unsigned int offset = SIM_attr_integer(SIM_attr_list_item(result, 3)); unsigned int ret = scnprintf(buf, maxlen, GLOBAL_COLOUR "%s", globalname); if (offset != 0) { ret += scnprintf(buf+ret, maxlen-ret, "+%d", offset); } ret += scnprintf(buf+ret, maxlen-ret, GLOBAL_INFO_COLOUR " (%s at 0x%.8x)" COLOUR_DEFAULT, typename, addr); SIM_free_attribute(result); SIM_free_attribute(idx); return ret; }