static void command_get_children(char * token, Channel * c) { int err = 0; char id[256]; Symbol sym; Symbol * list = NULL; int cnt = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (id2symbol(id, &sym) < 0) err = errno; if (err == 0 && get_symbol_children(&sym, &list, &cnt) < 0) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, 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); loc_free(list); }
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_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_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); }
int id2symbol(const char * id, Symbol ** res) { Symbol * sym = NULL; Context * ctx = NULL; ULONG64 module = 0; ULONG index = 0; unsigned frame = 0; const Symbol * base = NULL; const TypeInfo * info = NULL; size_t length = 0; const char * p; if (id != NULL && id[0] == '@' && id[1] == 'P') { p = id + 2; length = (size_t)read_hex(&p); if (*p == '.') p++; if (id2symbol(p, (Symbol **)&base)) return -1; ctx = base->ctx; } else if (id != NULL && id[0] == '@' && id[1] == 'S') { unsigned idx = 0; p = id + 2; module = (ULONG64)read_hex(&p); if (*p == '.') p++; index = (ULONG)read_hex(&p); if (*p == '.') p++; frame = (unsigned)read_hex(&p); if (*p == '.') p++; idx = (unsigned)read_hex(&p); if (idx) info = basic_type_info + (idx - 1); if (*p == '.') p++; ctx = id2ctx(p); } else { errno = ERR_INV_CONTEXT; return -1; } if (ctx == NULL) { errno = ERR_INV_CONTEXT; return -1; } sym = alloc_symbol(); sym->ctx = ctx; sym->module = module; sym->index = index; sym->frame = frame; sym->base = base; sym->info = info; sym->length = length; if (sym->base || sym->info) { sym->sym_class = SYM_CLASS_TYPE; } else { DWORD dword = 0; if (get_type_info(sym, TI_GET_SYMTAG, &dword) < 0) return -1; tag2symclass(sym, dword); } *res = sym; return 0; }
static void command_get_context(char * token, Channel * c) { int err = 0; char id[256]; Symbol sym; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (id2symbol(id, &sym) < 0) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err == 0) { char * name = NULL; int type_class = TYPE_CLASS_UNKNOWN; Symbol type; size_t size = 0; void * value = NULL; unsigned long length = 0; unsigned long offset = 0; ContextAddress address = 0; int frame = STACK_NO_FRAME; /* TODO: symbol frame */ write_stream(&c->out, '{'); json_write_string(&c->out, "ID"); write_stream(&c->out, ':'); json_write_string(&c->out, id); write_stream(&c->out, ','); json_write_string(&c->out, "ExeID"); write_stream(&c->out, ':'); json_write_string(&c->out, container_id(sym.ctx)); write_stream(&c->out, ','); if (get_symbol_name(&sym, &name) == 0 && name != NULL) { json_write_string(&c->out, "Name"); write_stream(&c->out, ':'); json_write_string(&c->out, name); write_stream(&c->out, ','); loc_free(name); } if (get_symbol_type_class(&sym, &type_class) == 0 && 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 (get_symbol_type(&sym, &type) == 0) { json_write_string(&c->out, "TypeID"); write_stream(&c->out, ':'); json_write_string(&c->out, symbol2id(&type)); write_stream(&c->out, ','); } if (get_symbol_base_type(&sym, &type) == 0) { json_write_string(&c->out, "BaseTypeID"); write_stream(&c->out, ':'); json_write_string(&c->out, symbol2id(&type)); write_stream(&c->out, ','); } if (get_symbol_index_type(&sym, &type) == 0) { json_write_string(&c->out, "IndexTypeID"); write_stream(&c->out, ':'); json_write_string(&c->out, symbol2id(&type)); write_stream(&c->out, ','); } if (get_symbol_size(&sym, frame, &size) == 0) { json_write_string(&c->out, "Size"); write_stream(&c->out, ':'); json_write_long(&c->out, size); write_stream(&c->out, ','); } if (get_symbol_length(&sym, frame, &length) == 0) { json_write_string(&c->out, "Length"); write_stream(&c->out, ':'); json_write_long(&c->out, length); write_stream(&c->out, ','); } if (sym.sym_class == SYM_CLASS_REFERENCE) { if (get_symbol_offset(&sym, &offset) == 0) { json_write_string(&c->out, "Offset"); write_stream(&c->out, ':'); json_write_long(&c->out, offset); write_stream(&c->out, ','); } if (get_symbol_address(&sym, frame, &address) == 0) { json_write_string(&c->out, "Address"); write_stream(&c->out, ':'); json_write_long(&c->out, address); write_stream(&c->out, ','); } } if (sym.sym_class == SYM_CLASS_VALUE && get_symbol_value(&sym, &value, &size) == 0) { json_write_string(&c->out, "Value"); write_stream(&c->out, ':'); json_write_binary(&c->out, value, size); write_stream(&c->out, ','); } json_write_string(&c->out, "Class"); write_stream(&c->out, ':'); json_write_long(&c->out, sym.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 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); }