static void command_find_in_scope_cache_client(void * x) { CommandFindInScopeArgs * args = (CommandFindInScopeArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; Symbol * scope = NULL; Symbol * sym = NULL; int err = 0; if (id2frame(args->frame_id, &ctx, &frame) < 0) ctx = id2ctx(args->frame_id); if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->frame_id); else if (ctx->exited) err = ERR_ALREADY_EXITED; if (err == 0 && args->scope_id[0] && id2symbol(args->scope_id, &scope) < 0) err = errno; if (err == 0 && args->name == NULL) err = set_errno(EINVAL, "Symbol name must not be null"); if (err == 0 && find_symbol_in_scope(ctx, frame, args->ip, scope, args->name, &sym) < 0) err = errno; list_cnt = 0; if (err == 0) { list_add(sym); while (find_next_symbol(&sym) == 0) list_add(sym); if (get_error_code(errno) != ERR_SYM_NOT_FOUND) err = errno; } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); write_symbol_list(&c->out); write_stream(&c->out, MARKER_EOM); loc_free(args->name); }
static void command_find_by_addr_cache_client(void * x) { CommandFindByAddrArgs * args = (CommandFindByAddrArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; Symbol * sym = NULL; int err = 0; if (id2frame(args->id, &ctx, &frame) < 0) ctx = id2ctx(args->id); if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->id); else if (ctx->exited) err = ERR_ALREADY_EXITED; if (err == 0 && find_symbol_by_addr(ctx, frame, args->addr, &sym) < 0) err = errno; list_cnt = 0; if (err == 0) { list_add(sym); while (find_next_symbol(&sym) == 0) list_add(sym); if (get_error_code(errno) != ERR_SYM_NOT_FOUND) err = errno; } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); write_symbol_list(&c->out); write_stream(&c->out, MARKER_EOM); }
static void command_get_array_type_cache_client(void * x) { CommandGetArrayTypeArgs * args = (CommandGetArrayTypeArgs *)x; Channel * c = cache_channel(); Symbol * sym = NULL; Symbol * arr = NULL; int err = 0; if (id2symbol(args->id, &sym) < 0) err = errno; if (err == 0 && get_array_symbol(sym, (ContextAddress)args->length, &arr) < 0) err = errno; cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); if (err == 0) { json_write_string(&c->out, symbol2id(arr)); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void command_get_context_cache_client(void * x) { GetContextArgs * args = (GetContextArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; RegisterDefinition * reg_def = NULL; Trap trap; if (set_trap(&trap)) { if (id2register(args->id, &ctx, &frame, ®_def) < 0) exception(errno); clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); if (reg_def != NULL) { write_context(&c->out, args->id, ctx, frame, reg_def); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void command_get_children_cache_client(void * x) { CommandGetChildrenArgs * args = (CommandGetChildrenArgs *)x; Channel * c = cache_channel(); int err = 0; Symbol * sym = NULL; Symbol ** list = NULL; int cnt = 0; if (id2symbol(args->id, &sym) < 0) err = errno; if (err == 0 && get_symbol_children(sym, &list, &cnt) < 0) err = errno; cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); if (err == 0) { int i; write_stream(&c->out, '['); for (i = 0; i < cnt; i++) { if (i > 0) write_stream(&c->out, ','); json_write_string(&c->out, symbol2id(list[i])); } write_stream(&c->out, ']'); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void command_reset_cache_client(void * x) { CommandResetArgs * args = (CommandResetArgs *)x; Channel * c = cache_channel(); Context * ctx = id2ctx(args->id); OutputStream * out = &c->out; int err = 0; if (ctx == NULL) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; if (!err) { Context * grp = get_reset_context(ctx); ResetInfo * rst = find_reset(grp, args->type); if (rst == NULL) err = set_errno(ERR_OTHER, "Unsupported reset type"); else if (rst->reset(ctx, &args->params) < 0) err = errno; } cache_exit(); while (args->params.list != NULL) { ResetParameter * p = args->params.list; args->params.list = p->next; loc_free(p->name); loc_free(p->value); loc_free(p); } write_stringz(out, "R"); write_stringz(out, args->token); write_errno(out, err); write_stream(out, MARKER_EOM); }
static void command_get_children_cache_client(void * x) { GetChildrenArgs * args = (GetChildrenArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; StackFrame * frame_info = NULL; RegisterDefinition * defs = NULL; RegisterDefinition * parent = NULL; Trap trap; if (set_trap(&trap)) { if (id2register(args->id, &ctx, &frame, &parent) == 0) { if (frame != STACK_TOP_FRAME && get_frame_info(ctx, frame, &frame_info) < 0) exception(errno); } else if (id2frame(args->id, &ctx, &frame) == 0) { if (get_frame_info(ctx, frame, &frame_info) < 0) exception(errno); } else { ctx = id2ctx(args->id); frame = STACK_TOP_FRAME; } if (ctx != NULL) defs = get_reg_definitions(ctx); clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); write_stream(&c->out, '['); if (defs != NULL) { int cnt = 0; RegisterDefinition * reg_def; for (reg_def = defs; reg_def->name != NULL; reg_def++) { if (reg_def->parent != parent) continue; if (frame < 0 || frame_info->is_top_frame || reg_def->size == 0 || read_reg_value(frame_info, reg_def, NULL) == 0) { if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, register2id(ctx, frame, reg_def)); cnt++; } } } write_stream(&c->out, ']'); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }
static void command_get_address_info_cache_client(void * x) { int err = 0; Channel * c = cache_channel(); CommandAddressInfo * args = (CommandAddressInfo *)x; Context * ctx = NULL; const char * isa = NULL; ContextAddress range_addr = 0; ContextAddress range_size = 0; ContextAddress plt = 0; ctx = id2ctx(args->id); if (ctx == NULL) err = ERR_INV_CONTEXT; if (!err && get_context_isa(ctx, args->addr, &isa, &range_addr, &range_size) < 0) err = errno; if (!err) plt = is_plt_section(ctx, args->addr); cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); if (!err) { write_stream(&c->out, '{'); json_write_string(&c->out, "Addr"); write_stream(&c->out, ':'); json_write_uint64(&c->out, range_addr); write_stream(&c->out, ','); json_write_string(&c->out, "Size"); write_stream(&c->out, ':'); json_write_uint64(&c->out, range_size); if (isa != NULL) { write_stream(&c->out, ','); json_write_string(&c->out, "ISA"); write_stream(&c->out, ':'); json_write_string(&c->out, isa); } if (plt != 0) { write_stream(&c->out, ','); json_write_string(&c->out, "PLT"); write_stream(&c->out, ':'); json_write_uint64(&c->out, plt); } write_stream(&c->out, '}'); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void command_get_cache_client(void * x) { GetArgs * args = (GetArgs *)x; Channel * c = cache_channel(); Trap trap; bbf_pos = 0; if (set_trap(&trap)) { int frame = 0; Context * ctx = NULL; RegisterDefinition * reg_def = NULL; if (id2register(args->id, &ctx, &frame, ®_def) < 0) exception(errno); if (ctx->exited) exception(ERR_ALREADY_EXITED); if ((ctx->reg_access & REG_ACCESS_RD_STOP) != 0) { check_all_stopped(ctx); } if ((ctx->reg_access & REG_ACCESS_RD_RUNNING) == 0) { if (!ctx->stopped && context_has_state(ctx)) str_exception(ERR_IS_RUNNING, "Cannot read register if not stopped"); } if (reg_def->size > bbf_len) { bbf_len += 0x100 + reg_def->size; bbf = (uint8_t *)loc_realloc(bbf, bbf_len); } bbf_pos = reg_def->size; memset(bbf, 0, reg_def->size); if (frame < 0 || is_top_frame(ctx, frame)) { if (context_read_reg(ctx, reg_def, 0, reg_def->size, bbf) < 0) exception(errno); } else { StackFrame * info = NULL; if (get_frame_info(ctx, frame, &info) < 0) exception(errno); if (read_reg_bytes(info, reg_def, 0, reg_def->size, bbf) < 0) exception(errno); } clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); json_write_binary(&c->out, bbf, bbf_pos); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }
static void command_setm_cache_client(void * x) { SetmArgs * args = (SetmArgs *)x; Channel * c = cache_channel(); int notify = 0; Trap trap; if (set_trap(&trap)) { unsigned locs_pos = 0; unsigned data_pos = 0; check_location_list(args->locs, args->locs_cnt, 1); while (locs_pos < args->locs_cnt) { Location * l = args->locs + locs_pos++; assert(l->frame_info == NULL); if (l->size > 0) { if (context_write_reg(l->ctx, l->reg_def, l->offs, l->size, args->data + data_pos) < 0) exception(errno); data_pos += l->size; l->notify = 1; notify = 1; } } clear_trap(&trap); } cache_exit(); if (notify) { unsigned locs_pos = 0; while (locs_pos < args->locs_cnt) { Location * l = args->locs + locs_pos++; if (l->notify) send_event_register_changed(l->id); } } write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); write_stream(&c->out, MARKER_EOM); loc_free(args->locs); loc_free(args->data); }
static void command_set_cache_client(void * x) { SetArgs * args = (SetArgs *)x; Channel * c = cache_channel(); int notify = 0; Trap trap; if (set_trap(&trap)) { int frame = 0; Context * ctx = NULL; RegisterDefinition * reg_def = NULL; if (id2register(args->id, &ctx, &frame, ®_def) < 0) exception(errno); if (frame >= 0 && !is_top_frame(ctx, frame)) exception(ERR_INV_CONTEXT); if (ctx->exited) exception(ERR_ALREADY_EXITED); if ((ctx->reg_access & REG_ACCESS_WR_STOP) != 0) { check_all_stopped(ctx); } if ((ctx->reg_access & REG_ACCESS_WR_RUNNING) == 0) { if (!ctx->stopped && context_has_state(ctx)) str_exception(ERR_IS_RUNNING, "Cannot write register if not stopped"); } if ((size_t)args->data_len > reg_def->size) exception(ERR_INV_DATA_SIZE); if (args->data_len > 0) { if (context_write_reg(ctx, reg_def, 0, args->data_len, args->data) < 0) exception(errno); notify = 1; } clear_trap(&trap); } cache_exit(); if (notify) send_event_register_changed(args->id); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); write_stream(&c->out, MARKER_EOM); loc_free(args->data); }
static void command_getm_cache_client(void * x) { GetmArgs * args = (GetmArgs *)x; Channel * c = cache_channel(); Trap trap; bbf_pos = 0; if (bbf == NULL) bbf = (uint8_t *)loc_alloc(bbf_len = 0x100); if (set_trap(&trap)) { unsigned locs_pos = 0; check_location_list(args->locs, args->locs_cnt, 0); while (locs_pos < args->locs_cnt) { Location * l = args->locs + locs_pos++; if (bbf_pos + l->size > bbf_len) { bbf_len += 0x100 + l->size; bbf = (uint8_t *)loc_realloc(bbf, bbf_len); } memset(bbf + bbf_pos, 0, l->size); if (l->frame_info == NULL) { if (context_read_reg(l->ctx, l->reg_def, l->offs, l->size, bbf + bbf_pos) < 0) exception(errno); } else { if (read_reg_bytes(l->frame_info, l->reg_def, l->offs, l->size, bbf + bbf_pos) < 0) exception(errno); } bbf_pos += l->size; } clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); json_write_binary(&c->out, bbf, bbf_pos); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); loc_free(args->locs); }
static void command_list_cache_client(void * x) { CommandListArgs * args = (CommandListArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; int err = 0; list_cnt = 0; if (id2frame(args->id, &ctx, &frame) < 0) ctx = id2ctx(args->id); if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->id); else if (ctx->exited) err = ERR_ALREADY_EXITED; if (err == 0 && enumerate_symbols(ctx, frame, list_callback, NULL) < 0) err = errno; cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); if (err == 0) { unsigned i = 0; write_stream(&c->out, '['); for (i = 0; i < list_cnt; i++) { if (i > 0) write_stream(&c->out, ','); json_write_string(&c->out, symbol2id(list_buf[i])); } write_stream(&c->out, ']'); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void command_get_capabilities_cache_client(void * x) { int error = 0; Context * ctx = NULL; ContextExtensionDS * ext = NULL; GetCapabilitiesCmdArgs * args = (GetCapabilitiesCmdArgs *)x; Channel * c = cache_channel(); ctx = id2ctx(args->id); if (ctx == NULL) error = ERR_INV_CONTEXT; else if (ctx->exited) error = ERR_ALREADY_EXITED; else ext = EXT(context_get_group(ctx, CONTEXT_GROUP_CPU)); cache_exit(); if (!is_channel_closed(c)) { OutputStream * out = &c->out; write_stringz(out, "R"); write_stringz(out, args->token); write_errno(out, error); write_stream(out, '['); if (ext != NULL) { unsigned i; for (i = 0; i < ext->disassemblers_cnt; i++) { if (i > 0) write_stream(out, ','); write_stream(out, '{'); json_write_string(out, "ISA"); write_stream(out, ':'); json_write_string(out, ext->disassemblers[i].isa); write_stream(out, '}'); } } write_stream(out, ']'); write_stream(out, 0); write_stream(out, MARKER_EOM); } }
static void command_find_frame_props_cache_client(void * x) { CommandFindFrameInfo * args = (CommandFindFrameInfo *)x; Channel * c = cache_channel(); Context * ctx = NULL; StackTracingInfo * info = NULL; int err = 0; ctx = id2ctx(args->id); if (ctx == NULL) err = ERR_INV_CONTEXT; else if (get_stack_tracing_info(ctx, args->addr, &info) < 0) err = errno; cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); if (args->props) { unsigned cnt = 0; write_stream(&c->out, '{'); if (info != NULL && info->size) { json_write_string(&c->out, "CodeAddr"); write_stream(&c->out, ':'); json_write_uint64(&c->out, info->addr); write_stream(&c->out, ','); json_write_string(&c->out, "CodeSize"); write_stream(&c->out, ':'); json_write_uint64(&c->out, info->size); cnt++; } if (info != NULL && info->fp != NULL) { if (cnt++ > 0) write_stream(&c->out, ','); json_write_string(&c->out, "FP"); write_stream(&c->out, ':'); write_commands(&c->out, ctx, info->fp->cmds, info->fp->cmds_cnt); } if (info != NULL && info->regs != NULL) { int i; if (cnt++ > 0) write_stream(&c->out, ','); json_write_string(&c->out, "Regs"); write_stream(&c->out, ':'); write_stream(&c->out, '{'); for (i = 0; i < info->reg_cnt; i++) { if (i > 0) write_stream(&c->out, ','); json_write_string(&c->out, register2id(ctx, STACK_NO_FRAME, info->regs[i]->reg)); write_stream(&c->out, ':'); write_commands(&c->out, ctx, info->regs[i]->cmds, info->regs[i]->cmds_cnt); } write_stream(&c->out, '}'); } if (info != NULL && info->subs != NULL) { int i; if (cnt++ > 0) write_stream(&c->out, ','); json_write_string(&c->out, "Inlined"); write_stream(&c->out, ':'); write_stream(&c->out, '['); for (i = 0; i < info->sub_cnt; i++) { if (i > 0) write_stream(&c->out, ','); write_inlined_subroutine_info(&c->out, info->subs[i]); } write_stream(&c->out, ']'); } write_stream(&c->out, '}'); write_stream(&c->out, 0); } else { /* Deprecated, use findFrameProps */ json_write_uint64(&c->out, info ? info->addr : 0); write_stream(&c->out, 0); json_write_uint64(&c->out, info ? info->size : 0); write_stream(&c->out, 0); if (info == NULL || info->fp == NULL) write_string(&c->out, "null"); else write_commands(&c->out, ctx, info->fp->cmds, info->fp->cmds_cnt); write_stream(&c->out, 0); if (info != NULL && info->regs != NULL) { int i; write_stream(&c->out, '{'); for (i = 0; i < info->reg_cnt; i++) { if (i > 0) write_stream(&c->out, ','); json_write_string(&c->out, register2id(ctx, STACK_NO_FRAME, info->regs[i]->reg)); write_stream(&c->out, ':'); write_commands(&c->out, ctx, info->regs[i]->cmds, info->regs[i]->cmds_cnt); } write_stream(&c->out, '}'); } else { write_string(&c->out, "null"); } write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
static void command_get_location_info_cache_client(void * x) { CommandGetLocationInfo * args = (CommandGetLocationInfo *)x; Channel * c = cache_channel(); LocationInfo * info = NULL; Context * ctx = NULL; int frame = STACK_NO_FRAME; Symbol * sym = NULL; int err = 0; if (id2symbol(args->id, &sym) < 0) err = errno; else if (get_location_info(sym, &info) < 0) err = errno; else if (get_symbol_frame(sym, &ctx, &frame) < 0) err = errno; cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); if (info == NULL) { write_stringz(&c->out, "null"); } else { write_stream(&c->out, '{'); json_write_string(&c->out, "BigEndian"); write_stream(&c->out, ':'); json_write_boolean(&c->out, info->big_endian); write_stream(&c->out, ','); json_write_string(&c->out, "ValueCmds"); write_stream(&c->out, ':'); write_commands(&c->out, ctx, info->value_cmds.cmds, info->value_cmds.cnt); if (info->args_cnt) { write_stream(&c->out, ','); json_write_string(&c->out, "ArgCnt"); write_stream(&c->out, ':'); json_write_ulong(&c->out, info->args_cnt); } if (info->code_size) { write_stream(&c->out, ','); json_write_string(&c->out, "CodeAddr"); write_stream(&c->out, ':'); json_write_uint64(&c->out, info->code_addr); write_stream(&c->out, ','); json_write_string(&c->out, "CodeSize"); write_stream(&c->out, ':'); json_write_uint64(&c->out, info->code_size); } if (info->discr_cnt > 0) { unsigned i; write_stream(&c->out, ','); json_write_string(&c->out, "Discriminant"); write_stream(&c->out, ':'); write_stream(&c->out, '['); for (i = 0; i < info->discr_cnt; i++) { DiscriminantRange * r = info->discr_lst + i; if (i > 0) write_stream(&c->out, ','); if (r->x == r->y) { json_write_int64(&c->out, r->x); } else { write_stream(&c->out, '{'); json_write_string(&c->out, "X"); write_stream(&c->out, ':'); json_write_int64(&c->out, r->x); write_stream(&c->out, ','); json_write_string(&c->out, "Y"); write_stream(&c->out, ':'); json_write_int64(&c->out, r->y); write_stream(&c->out, '}'); } } write_stream(&c->out, ']'); } write_stream(&c->out, '}'); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
static void command_get_context_cache_client(void * x) { CommandGetContextArgs * args = (CommandGetContextArgs *)x; Channel * c = cache_channel(); int err = 0; Symbol * sym = NULL; char * owner = NULL; char * name = NULL; int update_policy = 0; int sym_class = SYM_CLASS_UNKNOWN; int type_class = TYPE_CLASS_UNKNOWN; Symbol * type = NULL; Symbol * base = NULL; Symbol * index = NULL; Symbol * container = NULL; int has_size = 0; int has_length = 0; int has_lower_bound = 0; int has_offset = 0; int has_address = 0; int has_frame = 0; int big_endian = 0; ContextAddress size = 0; ContextAddress length = 0; int64_t lower_bound = 0; ContextAddress offset = 0; ContextAddress address = 0; RegisterDefinition * reg = NULL; SYM_FLAGS flags = 0; void * value = NULL; size_t value_size = 0; Context * ctx = NULL; int frame = STACK_NO_FRAME; SymbolProperties props; memset(&props, 0, sizeof(props)); if (id2symbol(args->id, &sym) < 0) err = errno; if (err == 0) { get_symbol_class(sym, &sym_class); get_symbol_update_policy(sym, &owner, &update_policy); get_symbol_name(sym, &name); get_symbol_type_class(sym, &type_class); get_symbol_type(sym, &type); get_symbol_base_type(sym, &base); get_symbol_index_type(sym, &index); get_symbol_container(sym, &container); has_frame = get_symbol_frame(sym, &ctx, &frame) == 0; has_size = get_symbol_size(sym, &size) == 0; if (type_class == TYPE_CLASS_ARRAY) { has_length = get_symbol_length(sym, &length) == 0; if (has_length) has_lower_bound = get_symbol_lower_bound(sym, &lower_bound) == 0; } if (sym_class == SYM_CLASS_REFERENCE || sym_class == SYM_CLASS_FUNCTION || sym_class == SYM_CLASS_VALUE || sym_class == SYM_CLASS_TYPE || sym_class == SYM_CLASS_VARIANT_PART) { LocationInfo * loc_info = NULL; if (has_frame && get_location_info(sym, &loc_info) == 0) { LocationExpressionState * state = NULL; if (loc_info->args_cnt == 0) { /* Absolute location */ state = evaluate_location(ctx, frame, loc_info); if (state != NULL) { if (state->stk_pos == 1) { address = (ContextAddress)state->stk[0]; has_address = 1; } if (state->pieces_cnt == 1 && state->pieces->reg != NULL && state->pieces->reg->size == state->pieces->size) { reg = state->pieces->reg; } if (state->pieces_cnt > 0) { Trap trap; if (set_trap(&trap)) { read_location_pieces(state->ctx, state->stack_frame, state->pieces, state->pieces_cnt, loc_info->big_endian, &value, &value_size); big_endian = loc_info->big_endian; clear_trap(&trap); } } } } else if (loc_info->args_cnt == 1) { /* Relative location */ state = evaluate_location(ctx, frame, loc_info); if (state != NULL && state->stk_pos == 1) { offset = (ContextAddress)state->stk[0]; has_offset = 1; } } } } get_symbol_flags(sym, &flags); get_symbol_props(sym, &props); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); if (err == 0) { write_stream(&c->out, '{'); json_write_string(&c->out, "ID"); write_stream(&c->out, ':'); json_write_string(&c->out, args->id); write_stream(&c->out, ','); if (owner != NULL) { json_write_string(&c->out, "OwnerID"); write_stream(&c->out, ':'); json_write_string(&c->out, owner); write_stream(&c->out, ','); json_write_string(&c->out, "UpdatePolicy"); write_stream(&c->out, ':'); json_write_long(&c->out, update_policy); write_stream(&c->out, ','); } if (name != NULL) { json_write_string(&c->out, "Name"); write_stream(&c->out, ':'); json_write_string(&c->out, name); write_stream(&c->out, ','); } if (type_class != TYPE_CLASS_UNKNOWN) { json_write_string(&c->out, "TypeClass"); write_stream(&c->out, ':'); json_write_long(&c->out, type_class); write_stream(&c->out, ','); } if (type != NULL) { json_write_string(&c->out, "TypeID"); write_stream(&c->out, ':'); json_write_string(&c->out, symbol2id(type)); write_stream(&c->out, ','); } if (base != NULL) { json_write_string(&c->out, "BaseTypeID"); write_stream(&c->out, ':'); json_write_string(&c->out, symbol2id(base)); write_stream(&c->out, ','); } if (index != NULL) { json_write_string(&c->out, "IndexTypeID"); write_stream(&c->out, ':'); json_write_string(&c->out, symbol2id(index)); write_stream(&c->out, ','); } if (container != NULL) { json_write_string(&c->out, "ContainerID"); write_stream(&c->out, ':'); json_write_string(&c->out, symbol2id(container)); write_stream(&c->out, ','); } if (has_size) { json_write_string(&c->out, "Size"); write_stream(&c->out, ':'); json_write_uint64(&c->out, size); write_stream(&c->out, ','); } if (has_length) { json_write_string(&c->out, "Length"); write_stream(&c->out, ':'); json_write_uint64(&c->out, length); write_stream(&c->out, ','); if (has_lower_bound) { json_write_string(&c->out, "LowerBound"); write_stream(&c->out, ':'); json_write_int64(&c->out, lower_bound); write_stream(&c->out, ','); json_write_string(&c->out, "UpperBound"); write_stream(&c->out, ':'); json_write_int64(&c->out, lower_bound + (int64_t)length - 1); write_stream(&c->out, ','); } } if (has_offset) { json_write_string(&c->out, "Offset"); write_stream(&c->out, ':'); json_write_uint64(&c->out, offset); write_stream(&c->out, ','); } if (has_address) { json_write_string(&c->out, "Address"); write_stream(&c->out, ':'); json_write_uint64(&c->out, address); write_stream(&c->out, ','); } if (reg != NULL && has_frame) { json_write_string(&c->out, "Register"); write_stream(&c->out, ':'); json_write_string(&c->out, register2id(ctx, frame, reg)); write_stream(&c->out, ','); } if (flags) { json_write_string(&c->out, "Flags"); write_stream(&c->out, ':'); json_write_long(&c->out, flags); write_stream(&c->out, ','); } if (props.binary_scale != 0) { json_write_string(&c->out, "BinaryScale"); write_stream(&c->out, ':'); json_write_long(&c->out, props.binary_scale); write_stream(&c->out, ','); } if (props.decimal_scale != 0) { json_write_string(&c->out, "DecimalScale"); write_stream(&c->out, ':'); json_write_long(&c->out, props.decimal_scale); write_stream(&c->out, ','); } if (props.bit_stride != 0) { json_write_string(&c->out, "BitStride"); write_stream(&c->out, ':'); json_write_ulong(&c->out, props.bit_stride); write_stream(&c->out, ','); } if (props.local_entry_offset != 0) { json_write_string(&c->out, "LocalEntryOffset"); write_stream(&c->out, ':'); json_write_ulong(&c->out, props.local_entry_offset); write_stream(&c->out, ','); } if (value != NULL) { json_write_string(&c->out, "Value"); write_stream(&c->out, ':'); json_write_binary(&c->out, value, value_size); write_stream(&c->out, ','); if (big_endian) { json_write_string(&c->out, "BigEndian"); write_stream(&c->out, ':'); json_write_boolean(&c->out, 1); write_stream(&c->out, ','); } } if (has_frame && frame != STACK_NO_FRAME) { json_write_string(&c->out, "Frame"); write_stream(&c->out, ':'); json_write_long(&c->out, frame); write_stream(&c->out, ','); } json_write_string(&c->out, "Class"); write_stream(&c->out, ':'); json_write_long(&c->out, sym_class); write_stream(&c->out, '}'); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void disassemble_cache_client(void * x) { DisassembleCmdArgs * args = (DisassembleCmdArgs *)x; int error = 0; Context * ctx = NULL; uint8_t * mem_buf = NULL; ContextAddress buf_addr = 0; ContextAddress buf_size = 0; size_t mem_size = 0; ByteArrayOutputStream buf; OutputStream * buf_out = create_byte_array_output_stream(&buf); Channel * c = cache_channel(); char * data = NULL; size_t size = 0; ContextISA isa; memset(&isa, 0, sizeof(isa)); ctx = id2ctx(args->id); if (ctx == NULL) error = ERR_INV_CONTEXT; else if (ctx->exited) error = ERR_ALREADY_EXITED; if (!error) check_all_stopped(ctx); if (!error) { ContextAddress sym_addr = 0; ContextAddress sym_size = 0; int sym_addr_ok = 0; int sym_size_ok = 0; #if SERVICE_Symbols { Symbol * sym = NULL; if (find_symbol_by_addr(ctx, STACK_NO_FRAME, args->addr, &sym) == 0) { if (get_symbol_address(sym, &sym_addr) == 0) sym_addr_ok = 1; if (get_symbol_size(sym, &sym_size) == 0) sym_size_ok = 1; } if (sym_addr_ok && sym_addr <= args->addr) { if (args->addr - sym_addr >= 0x1000) { sym_addr_ok = 0; sym_size_ok = 0; } else if (sym_size_ok && sym_addr + sym_size > args->addr + args->size) { sym_size = args->addr + args->size - sym_addr; } } } #endif #if SERVICE_LineNumbers if (!sym_addr_ok || !sym_size_ok) { CodeArea * area = NULL; address_to_line(ctx, args->addr, args->addr + 1, address_to_line_cb, &area); if (area != NULL) { sym_addr = area->start_address; sym_size = area->end_address - area->start_address; sym_addr_ok = 1; sym_size_ok = 1; } } #endif if (sym_addr_ok && sym_size_ok && sym_addr <= args->addr && sym_addr + sym_size > args->addr) { buf_addr = sym_addr; buf_size = sym_size; mem_size = (size_t)sym_size; } else if (sym_addr_ok && sym_addr < args->addr) { if (get_isa(ctx, sym_addr, &isa) < 0) { error = errno; } else { buf_addr = sym_addr; buf_size = args->addr + args->size - sym_addr; if (isa.max_instruction_size > 0) { mem_size = (size_t)(buf_size + isa.max_instruction_size); } else { mem_size = (size_t)(buf_size + MAX_INSTRUCTION_SIZE); } } } else { /* Use default address alignment */ if (get_isa(ctx, args->addr, &isa) < 0) { error = errno; } else { if (isa.alignment > 0) { buf_addr = args->addr & ~(ContextAddress)(isa.alignment - 1); } else { buf_addr = args->addr & ~(ContextAddress)(DEFAULT_ALIGMENT - 1); } buf_size = args->addr + args->size - buf_addr; if (isa.max_instruction_size > 0) { mem_size = (size_t)(buf_size + isa.max_instruction_size); } else { mem_size = (size_t)(buf_size + MAX_INSTRUCTION_SIZE); } } } if (!error) { mem_buf = (uint8_t *)tmp_alloc(mem_size); if (context_read_mem(ctx, buf_addr, mem_buf, mem_size) < 0) error = errno; if (error) { #if ENABLE_ExtendedMemoryErrorReports MemoryErrorInfo info; if (context_get_mem_error_info(&info) == 0 && info.size_valid > 0) { mem_size = info.size_valid; error = 0; } #endif } } } if (!error && disassemble_block( ctx, buf_out, mem_buf, buf_addr, buf_size, mem_size, &isa, args) < 0) error = errno; if (get_error_code(error) == ERR_CACHE_MISS) { loc_free(buf.mem); buf.mem = NULL; buf.max = 0; buf.pos = 0; } cache_exit(); get_byte_array_output_stream_data(&buf, &data, &size); if (!is_channel_closed(c)) { OutputStream * out = &c->out; write_stringz(out, "R"); write_stringz(out, args->token); write_errno(out, error); if (size > 0) { write_block_stream(out, data, size); } else { write_string(out, "null"); } write_stream(out, 0); write_stream(out, MARKER_EOM); } loc_free(data); }
static void command_get_sym_file_info_cache_client(void * x) { int err = 0; MemoryMap * client_map = NULL; MemoryMap * target_map = NULL; MemoryRegion * region = NULL; Channel * c = cache_channel(); CommandSymFileInfo * args = (CommandSymFileInfo *)x; const char * sym_file = NULL; Context * ctx = NULL; int sym_error = 0; ctx = id2ctx(args->id); if (ctx == NULL) err = ERR_INV_CONTEXT; if (!err && memory_map_get(ctx, &client_map, &target_map) < 0) err = errno; if (!err) { unsigned i; for (i = 0; i < client_map->region_cnt; i++) { MemoryRegion * r = client_map->regions + i; if (r->addr <= args->addr && r->addr + r->size > args->addr) region = r; } if (region == NULL) { for (i = 0; i < target_map->region_cnt; i++) { MemoryRegion * r = target_map->regions + i; if (r->addr <= args->addr && r->addr + r->size > args->addr) region = r; } } #if ENABLE_ELF /* TODO: need a generic way to support ELF program headers in getSymFileInfo command */ if (region == NULL) { static MemoryMap map; extern int elf_get_map(Context * ctx, ContextAddress addr0, ContextAddress addr1, MemoryMap * map); if (elf_get_map(ctx, args->addr, args->addr, &map) == 0) { for (i = 0; i < map.region_cnt; i++) { MemoryRegion * r = map.regions + i; if (r->addr <= args->addr && r->addr + r->size > args->addr) region = r; } } } #endif sym_file = get_symbol_file_name(ctx, region); sym_error = errno; } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); if (region != NULL) { write_stream(&c->out, '{'); json_write_string(&c->out, "Addr"); write_stream(&c->out, ':'); json_write_uint64(&c->out, region->addr); write_stream(&c->out, ','); json_write_string(&c->out, "Size"); write_stream(&c->out, ':'); json_write_uint64(&c->out, region->size); if (sym_file != NULL) { write_stream(&c->out, ','); json_write_string(&c->out, "FileName"); write_stream(&c->out, ':'); json_write_string(&c->out, sym_file); } if (sym_error != 0) { write_stream(&c->out, ','); json_write_string(&c->out, "FileError"); write_stream(&c->out, ':'); write_error_object(&c->out, sym_error); } write_stream(&c->out, '}'); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }