void cause_keypress(conf_object_t *kbd, char key) { bool do_shift = i8042_shift_key(&key); int keycode = i8042_key(key); attr_value_t i = SIM_make_attr_integer(keycode); attr_value_t v = SIM_make_attr_integer(0); /* see i8042 docs */ /* keycode value for shift found by trial and error :< */ attr_value_t shift = SIM_make_attr_integer(72); set_error_t ret; /* press key */ if (do_shift) { ret = SIM_set_attribute_idx(kbd, "key_event", &shift, &v); assert(ret == Sim_Set_Ok && "shift press failed!"); } ret = SIM_set_attribute_idx(kbd, "key_event", &i, &v); assert(ret == Sim_Set_Ok && "cause_keypress press failed!"); /* release key */ v = SIM_make_attr_integer(1); ret = SIM_set_attribute_idx(kbd, "key_event", &i, &v); assert(ret == Sim_Set_Ok && "cause_keypress release failed!"); if (do_shift) { ret = SIM_set_attribute_idx(kbd, "key_event", &shift, &v); assert(ret == Sim_Set_Ok && "cause_keypress release failed!"); } }
static attr_value_t get_written_value(void *dont_care, conf_object_t *obj, attr_value_t *idx) { sample_i2c_device_t *dev = (sample_i2c_device_t *)obj; return SIM_make_attr_integer(dev->written_value); }
/* 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; }
static attr_value_t get_range_sum_attribute(void *arg, conf_object_t *obj, attr_value_t *idx) { if (idx->kind != Sim_Val_List || idx->u.list.size != 2) { SIM_attribute_error("Attribute list-indexed with 2 entries"); return SIM_make_attr_invalid(); } attr_value_t *index = idx->u.list.vector; if (index[0].kind != Sim_Val_Integer || index[1].kind != Sim_Val_Integer) { SIM_attribute_error("Only integers in index list allowed"); return SIM_make_attr_invalid(); } integer_t start = MIN(index[0].u.integer, index[1].u.integer); integer_t end = MAX(index[0].u.integer, index[1].u.integer); integer_t sum = 0; for (integer_t i = start; i <= end; i++) sum += i; return SIM_make_attr_integer(sum); }
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; }
*offset = eip - SIM_attr_integer(func); SIM_free_attribute(result); SIM_free_attribute(idx); return true; } /* Attempts to find an object of the given type in the global data region, and * learn its size. Writes to 'result' and returns true if successful. */ bool find_user_global_of_type(const char *typename, unsigned int *size_result) { #if defined(USER_DATA_START) && defined(USER_IMG_END) char *get_global_name_at(conf_object_t *table, unsigned int addr, const char *typename) { 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); lsprintf(ALWAYS, "fail\n"); return NULL; } assert(SIM_attr_list_size(result) >= 3); attr_value_t name = SIM_attr_list_item(result, 1); attr_value_t type = SIM_attr_list_item(result, 2); assert(SIM_attr_is_string(name)); assert(SIM_attr_is_string(type)); char *global_name; if (strncmp(SIM_attr_string(type), typename, strlen(typename)+1) == 0) {
static attr_value_t get_value_attribute(void *arg, conf_object_t *obj, attr_value_t *idx) { sample_device_t *sample = (sample_device_t *)obj; return SIM_make_attr_integer(sample->value); }
static attr_value_t get_ls_arbiter_choice_attribute( void *arg, conf_object_t *obj, attr_value_t *idx) { return SIM_make_attr_integer(-42); }
static attr_value_t get_ls_decision_trace_attribute( void *arg, conf_object_t *obj, attr_value_t *idx) { return SIM_make_attr_integer(0x15410de0u); }