static void command_get_signal_mask(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid; Context * ctx = NULL; 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); pid = id2pid(id, NULL); ctx = context_find_from_pid(pid); if (ctx == NULL) err = ERR_INV_CONTEXT; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (ctx == NULL) { write_stringz(&c->out, "null"); write_stringz(&c->out, "null"); write_stringz(&c->out, "null"); } else { json_write_long(&c->out, ctx->sig_dont_stop); write_stream(&c->out, 0); json_write_long(&c->out, ctx->sig_dont_pass); write_stream(&c->out, 0); json_write_long(&c->out, ctx->pending_signals); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
static void command_read(char * token, Channel * c) { char id[256]; size_t size; int err = 0; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); size = json_read_ulong(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); if (virtual_stream_read(c, token, id, size) < 0) err = errno; if (err != 0) { /* * Handle reply with an error. If none error was detected, the reply * was sent back by virtual_stream_read() or delayed. */ write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_stringz(&c->out, "null"); write_errno(&c->out, err); json_write_long(&c->out, 0); write_stream(&c->out, 0); json_write_boolean(&c->out, 0); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); } }
static int send_packet(PortConnection * conn, char * buffer, size_t size) { JsonWriteBinaryState state; assert (is_dispatch_thread()); assert (conn->pending_write_request < MAX_STREAM_WRITE); protocol_send_command(conn->server->channel, "Streams", "write", write_stream_done, conn); json_write_string(&conn->server->channel->out, conn->out_stream_id); write_stream(&conn->server->channel->out, 0); json_write_long(&conn->server->channel->out, size); write_stream(&conn->server->channel->out, MARKER_EOA); json_write_binary_start(&state, &conn->server->channel->out, size); json_write_binary_data(&state, buffer, size); json_write_binary_end(&state); write_stream(&conn->server->channel->out, MARKER_EOA); write_stream(&conn->server->channel->out, MARKER_EOM); conn->pending_write_request ++; if (conn->pending_write_request == MAX_STREAM_WRITE) { return 0; } else { send_packet_callback(conn, 0); } return 0; }
static void send_read_reply(StreamClient * client, char * token, size_t size) { VirtualStream * stream = client->stream; Channel * c = client->channel; unsigned lost = 0; unsigned read1 = 0; unsigned read2 = 0; int eos = 0; char * data1 = NULL; char * data2 = NULL; unsigned pos = 0; unsigned len = (stream->buf_inp + stream->buf_len - stream->buf_out) % stream->buf_len; assert(len > 0 || stream->eos); assert(client->pos <= stream->pos); if ((uint64_t)len < stream->pos - client->pos) { lost = (long)(stream->pos - client->pos - len); } else { len = (unsigned)(stream->pos - client->pos); } pos = (stream->buf_inp + stream->buf_len - len) % stream->buf_len; if (len > size) len = size; data1 = stream->buf + pos; if (pos + len <= stream->buf_len) { read1 = len; } else { read1 = stream->buf_len - pos; data2 = stream->buf; read2 = len - read1; } assert(read1 + read2 == len); client->pos += lost + read1 + read2; assert(client->pos <= stream->pos); if (client->pos == stream->pos && stream->eos) eos = 1; assert(eos || lost + read1 + read2 > 0); write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (read1 + read2 > 0) { JsonWriteBinaryState state; json_write_binary_start(&state, &c->out, read1 + read2); json_write_binary_data(&state, data1, read1); json_write_binary_data(&state, data2, read2); json_write_binary_end(&state); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_errno(&c->out, 0); json_write_long(&c->out, lost); write_stream(&c->out, 0); json_write_boolean(&c->out, eos); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); flush_stream(&c->out); }
static void command_user(char * token, Channel * c) { if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); write_stringz(&c->out, "R"); write_stringz(&c->out, token); json_write_long(&c->out, getuid()); write_stream(&c->out, 0); json_write_long(&c->out, geteuid()); write_stream(&c->out, 0); json_write_long(&c->out, getgid()); write_stream(&c->out, 0); json_write_long(&c->out, getegid()); write_stream(&c->out, 0); json_write_string(&c->out, get_user_home()); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }
static void write_file_attrs(OutputStream * out, FileAttrs * attrs) { int cnt = 0; if (attrs == NULL) { write_stringz(out, "null"); return; } write_stream(out, '{'); if (attrs->flags & ATTR_SIZE) { json_write_string(out, "Size"); write_stream(out, ':'); json_write_int64(out, attrs->size); cnt++; } if (attrs->flags & ATTR_UIDGID) { if (cnt) write_stream(out, ','); json_write_string(out, "UID"); write_stream(out, ':'); json_write_long(out, attrs->uid); write_stream(out, ','); json_write_string(out, "GID"); write_stream(out, ':'); json_write_long(out, attrs->gid); cnt++; } if (attrs->flags & ATTR_SIZE) { if (cnt) write_stream(out, ','); json_write_string(out, "Permissions"); write_stream(out, ':'); json_write_long(out, attrs->permissions); cnt++; } if (attrs->flags & ATTR_ACMODTIME) { if (cnt) write_stream(out, ','); json_write_string(out, "ATime"); write_stream(out, ':'); json_write_int64(out, attrs->atime); write_stream(out, ','); json_write_string(out, "MTime"); write_stream(out, ':'); json_write_int64(out, attrs->mtime); cnt++; } write_stream(out, '}'); }
static void command_get_signal_list(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid; 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); pid = id2pid(id, NULL); write_stringz(&c->out, "R"); write_stringz(&c->out, token); /* pid is ignored, same signal list for all */ write_errno(&c->out, err); if (err) { write_stringz(&c->out, "null"); } else { int i = 0; int n = 0; write_stream(&c->out, '['); for (i = 0; i < 32; i++) { char * name = signal_name(i); char * desc = signal_description(i); if (name != NULL || desc != NULL) { if (n > 0) write_stream(&c->out, ','); write_stream(&c->out, '{'); json_write_string(&c->out, "Index"); write_stream(&c->out, ':'); json_write_long(&c->out, i); if (name != NULL) { write_stream(&c->out, ','); json_write_string(&c->out, "Name"); write_stream(&c->out, ':'); json_write_string(&c->out, name); } if (desc != NULL) { write_stream(&c->out, ','); json_write_string(&c->out, "Description"); write_stream(&c->out, ':'); json_write_string(&c->out, desc); } write_stream(&c->out, ','); json_write_string(&c->out, "Code"); write_stream(&c->out, ':'); json_write_ulong(&c->out, signal_code(i)); write_stream(&c->out, '}'); n++; } } write_stream(&c->out, ']'); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
static void send_event_terminal_win_size_changed(OutputStream * out, Terminal * term) { unsigned ws_col = 0; unsigned ws_row = 0; get_process_tty_win_size(term->prs, &ws_col, &ws_row); write_stringz(out, "E"); write_stringz(out, TERMINALS); write_stringz(out, "winSizeChanged"); json_write_string(out, tid2id(get_process_pid(term->prs))); write_stream(out, 0); json_write_long(out, ws_col); write_stream(out, 0); json_write_long(out, ws_row); write_stream(out, 0); write_stream(out, MARKER_EOM); }
static void send_event_process_exited(OutputStream * out, ChildProcess * prs) { write_stringz(out, "E"); write_stringz(out, PROCESSES); write_stringz(out, "exited"); json_write_string(out, pid2id(prs->pid, 0)); write_stream(out, 0); json_write_long(out, prs->exit_code); write_stream(out, 0); write_stream(out, MARKER_EOM); }
static void write_context_state(OutputStream * out, Context * ctx) { int fst = 1; assert(!ctx->exited); if (!ctx->intercepted) { write_stringz(out, "0"); write_stringz(out, "null"); write_stringz(out, "null"); return; } /* Number: PC */ json_write_ulong(out, get_regs_PC(ctx->regs)); write_stream(out, 0); /* String: Reason */ json_write_string(out, context_suspend_reason(ctx)); write_stream(out, 0); /* Object: Additional context state info */ write_stream(out, '{'); if (ctx->signal) { json_write_string(out, "Signal"); write_stream(out, ':'); json_write_long(out, ctx->signal); if (signal_name(ctx->signal)) { write_stream(out, ','); json_write_string(out, "SignalName"); write_stream(out, ':'); json_write_string(out, signal_name(ctx->signal)); } fst = 0; } if (ctx->stopped_by_bp && ctx->bp_ids != NULL && ctx->bp_ids[0] != NULL) { int i = 0; if (!fst) write_stream(out, ','); json_write_string(out, "BPs"); write_stream(out, ':'); write_stream(out, '['); while (ctx->bp_ids[i] != NULL) { if (i > 0) write_stream(out, ','); json_write_string(out, ctx->bp_ids[i++]); } write_stream(out, ']'); fst = 0; } write_stream(out, '}'); write_stream(out, 0); }
static void command_read(char * token, Channel * c) { char id[256]; size_t size = 0; StreamClient * client = NULL; int err = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); size = json_read_ulong(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); client = find_client(id, c); if (client == NULL) err = errno; if (!err && (client->stream->access & VS_ENABLE_REMOTE_READ) == 0) err = ERR_UNSUPPORTED; if (err == 0) { VirtualStream * stream = client->stream; if (client->pos == stream->pos && !stream->eos) { ReadRequest * r = loc_alloc_zero(sizeof(ReadRequest)); list_init(&r->link_client); r->client = client; r->size = size; strncpy(r->token, token, sizeof(r->token) - 1); list_add_last(&r->link_client, &client->read_requests); } else { assert(list_is_empty(&client->read_requests)); assert(client->channel == c); send_read_reply(client, token, size); advance_stream_buffer(stream); } } else { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_stringz(&c->out, "null"); write_errno(&c->out, err); json_write_long(&c->out, 0); write_stream(&c->out, 0); json_write_boolean(&c->out, 0); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); } }
static int read_packet(PortConnection * conn, int idx) { assert (is_dispatch_thread()); assert ((conn->pending_read_request & (1 << idx)) == 0); if (conn->pending_read_request & (1 << idx)) { errno = ERR_IS_RUNNING; return -1; } port_lock(conn); conn->pending_read_request |= (1 << idx); (void) protocol_send_command(conn->server->channel, "Streams", "read", read_stream_done, &conn->read_info[idx]); json_write_string(&conn->server->channel->out, conn->in_stream_id); write_stream(&conn->server->channel->out, 0); json_write_long(&conn->server->channel->out, sizeof conn->read_buffer[idx]); write_stream(&conn->server->channel->out, MARKER_EOA); write_stream(&conn->server->channel->out, MARKER_EOM); return 0; }
static void delete_read_request(ReadRequest * r) { Channel * c = r->client->channel; Trap trap; if (set_trap(&trap)) { write_stringz(&c->out, "R"); write_stringz(&c->out, r->token); write_stringz(&c->out, "null"); write_errno(&c->out, ERR_COMMAND_CANCELLED); json_write_long(&c->out, 0); write_stream(&c->out, 0); json_write_boolean(&c->out, 1); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); clear_trap(&trap); } else { trace(LOG_ALWAYS, "Exception handling pending stream read command: %d %s", trap.error, errno_to_str(trap.error)); } list_remove(&r->link_client); loc_free(r); }
static void write_context(OutputStream * out, char * id, Context * ctx, int frame, RegisterDefinition * reg_def) { assert(!ctx->exited); write_stream(out, '{'); json_write_string(out, "ID"); write_stream(out, ':'); json_write_string(out, id); write_stream(out, ','); json_write_string(out, "ParentID"); write_stream(out, ':'); if (reg_def->parent != NULL) { json_write_string(out, register2id(ctx, frame, reg_def->parent)); } else if (frame < 0 || is_top_frame(ctx, frame)) { json_write_string(out, ctx->id); } else { json_write_string(out, frame2id(ctx, frame)); } write_stream(out, ','); json_write_string(out, "ProcessID"); write_stream(out, ':'); json_write_string(out, context_get_group(ctx, CONTEXT_GROUP_PROCESS)->id); write_stream(out, ','); json_write_string(out, "Name"); write_stream(out, ':'); json_write_string(out, reg_def->name); if (reg_def->size > 0) { write_stream(out, ','); json_write_string(out, "Size"); write_stream(out, ':'); json_write_long(out, reg_def->size); } if (reg_def->dwarf_id >= 0) { write_stream(out, ','); json_write_string(out, "DwarfID"); write_stream(out, ':'); json_write_long(out, reg_def->dwarf_id); } if (reg_def->eh_frame_id >= 0) { write_stream(out, ','); json_write_string(out, "EhFrameID"); write_stream(out, ':'); json_write_long(out, reg_def->eh_frame_id); } write_boolean_member(out, "BigEndian", reg_def->big_endian); write_boolean_member(out, "Float", reg_def->fp_value); write_boolean_member(out, "Readable", !reg_def->no_read); write_boolean_member(out, "Writeable", !reg_def->no_write); write_boolean_member(out, "ReadOnce", reg_def->read_once); write_boolean_member(out, "WriteOnce", reg_def->write_once); write_boolean_member(out, "Volatile", reg_def->volatile_value); write_boolean_member(out, "SideEffects", reg_def->side_effects); write_boolean_member(out, "LeftToRight", reg_def->left_to_right); if (reg_def->first_bit > 0) { write_stream(out, ','); json_write_string(out, "FirstBit"); write_stream(out, ':'); json_write_long(out, reg_def->first_bit); } if (reg_def->bits != NULL) { int i = 0; write_stream(out, ','); json_write_string(out, "Bits"); write_stream(out, ':'); write_stream(out, '['); while (reg_def->bits[i] >= 0) { if (i > 0) write_stream(out, ','); json_write_long(out, reg_def->bits[i++]); } write_stream(out, ']'); } if (reg_def->values != NULL) { int i = 0; write_stream(out, ','); json_write_string(out, "Values"); write_stream(out, ':'); write_stream(out, '['); while (reg_def->values[i] != NULL) { NamedRegisterValue * v = reg_def->values[i++]; if (i > 1) write_stream(out, ','); write_stream(out, '{'); json_write_string(out, "Value"); write_stream(out, ':'); json_write_binary(out, v->value, reg_def->size); if (v->name != NULL) { write_stream(out, ','); json_write_string(out, "Name"); write_stream(out, ':'); json_write_string(out, v->name); } if (v->description != NULL) { write_stream(out, ','); json_write_string(out, "Description"); write_stream(out, ':'); json_write_string(out, v->description); } write_stream(out, '}'); } write_stream(out, ']'); } if (reg_def->memory_address > 0) { write_stream(out, ','); json_write_string(out, "MemoryAddress"); write_stream(out, ':'); json_write_uint64(out, reg_def->memory_address); } if (reg_def->memory_context != NULL) { write_stream(out, ','); json_write_string(out, "MemoryContext"); write_stream(out, ':'); json_write_string(out, reg_def->memory_context); } if (reg_def->role != NULL) { write_stream(out, ','); json_write_string(out, "Role"); write_stream(out, ':'); json_write_string(out, reg_def->role); } else if (reg_def == get_PC_definition(ctx)) { write_stream(out, ','); json_write_string(out, "Role"); write_stream(out, ':'); json_write_string(out, "PC"); } if (reg_def->description != NULL) { write_stream(out, ','); json_write_string(out, "Description"); write_stream(out, ':'); json_write_string(out, reg_def->description); } if (reg_def->size > 0) { RegisterDefinition * parent_reg_def = NULL; parent_reg_def = reg_def->parent; while (parent_reg_def != NULL && parent_reg_def->size == 0) parent_reg_def = parent_reg_def->parent; if (parent_reg_def != NULL) { if (reg_def->offset >= parent_reg_def->offset && reg_def->offset + reg_def->size <= parent_reg_def->offset + parent_reg_def->size) { write_stream(out, ','); json_write_string(out, "Offset"); write_stream(out, ':'); json_write_uint64(out, reg_def->offset - parent_reg_def->offset); } } } write_stream(out, '}'); write_stream(out, 0); }
static void write_context(OutputStream * out, Context * ctx, int is_thread) { assert(!ctx->exited); write_stream(out, '{'); json_write_string(out, "ID"); write_stream(out, ':'); json_write_string(out, is_thread ? thread_id(ctx) : container_id(ctx)); if (is_thread) { write_stream(out, ','); json_write_string(out, "ParentID"); write_stream(out, ':'); json_write_string(out, container_id(ctx)); } #if !defined(_WRS_KERNEL) write_stream(out, ','); json_write_string(out, "ProcessID"); write_stream(out, ':'); json_write_string(out, pid2id(ctx->mem, 0)); #endif #if !defined(WIN32) && !defined(_WRS_KERNEL) if (!ctx->exiting && !is_thread) { write_stream(out, ','); json_write_string(out, "File"); write_stream(out, ':'); json_write_string(out, get_executable(ctx->pid)); } #endif if (is_thread) { write_stream(out, ','); json_write_string(out, "CanSuspend"); write_stream(out, ':'); json_write_boolean(out, 1); write_stream(out, ','); json_write_string(out, "CanResume"); write_stream(out, ':'); json_write_long(out, (1 << RM_RESUME) | (1 << RM_STEP_INTO)); write_stream(out, ','); json_write_string(out, "HasState"); write_stream(out, ':'); json_write_boolean(out, 1); } #ifdef WIN32 if (!is_thread) #endif { write_stream(out, ','); json_write_string(out, "CanTerminate"); write_stream(out, ':'); json_write_boolean(out, 1); } write_stream(out, '}'); }
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 write_commands(OutputStream * out, Context * ctx, LocationExpressionCommand * cmds, unsigned cnt) { if (cmds != NULL) { unsigned i; write_stream(out, '['); for (i = 0; i < cnt; i++) { LocationExpressionCommand * cmd = cmds + i; if (i > 0) write_stream(out, ','); json_write_long(out, cmd->cmd); switch (cmd->cmd) { case SFT_CMD_NUMBER: write_stream(out, ','); json_write_int64(out, cmd->args.num); break; case SFT_CMD_ARG: case SFT_CMD_SET_ARG: write_stream(out, ','); json_write_ulong(out, cmd->args.arg_no); break; case SFT_CMD_RD_REG: case SFT_CMD_WR_REG: write_stream(out, ','); json_write_string(out, register2id(ctx, STACK_NO_FRAME, cmd->args.reg)); break; case SFT_CMD_RD_MEM: case SFT_CMD_WR_MEM: case SFT_CMD_LOAD: write_stream(out, ','); json_write_ulong(out, cmd->args.mem.size); write_stream(out, ','); json_write_boolean(out, cmd->args.mem.big_endian); break; case SFT_CMD_LOCATION: write_stream(out, ','); json_write_binary(out, cmd->args.loc.code_addr, cmd->args.loc.code_size); write_stream(out, ','); write_stream(out, '{'); json_write_string(out, "Machine"); write_stream(out, ':'); json_write_long(out, cmd->args.loc.reg_id_scope.machine); write_stream(out, ','); if (cmd->args.loc.reg_id_scope.os_abi) { json_write_string(out, "ABI"); write_stream(out, ':'); json_write_long(out, cmd->args.loc.reg_id_scope.os_abi); write_stream(out, ','); } if (cmd->args.loc.reg_id_scope.fp_abi) { json_write_string(out, "FPABI"); write_stream(out, ':'); json_write_long(out, cmd->args.loc.reg_id_scope.fp_abi); write_stream(out, ','); } json_write_string(out, "ELF64"); write_stream(out, ':'); json_write_boolean(out, cmd->args.loc.reg_id_scope.elf64); write_stream(out, ','); json_write_string(out, "RegIdType"); write_stream(out, ':'); json_write_long(out, cmd->args.loc.reg_id_scope.id_type); write_stream(out, ','); json_write_string(out, "AddrSize"); write_stream(out, ':'); json_write_long(out, cmd->args.loc.addr_size); write_stream(out, ','); json_write_string(out, "BigEndian"); write_stream(out, ':'); json_write_boolean(out, cmd->args.loc.reg_id_scope.big_endian); write_stream(out, '}'); break; case SFT_CMD_PIECE: write_stream(out, ','); json_write_ulong(out, cmd->args.piece.bit_offs); write_stream(out, ','); json_write_ulong(out, cmd->args.piece.bit_size); write_stream(out, ','); if (cmd->args.piece.reg == NULL) write_string(out, "null"); else json_write_string(out, register2id(ctx, STACK_NO_FRAME, cmd->args.piece.reg)); write_stream(out, ','); if (cmd->args.piece.value == NULL) write_string(out, "null"); else json_write_binary(out, cmd->args.piece.value, (cmd->args.piece.bit_size + 7) / 8); break; } } write_stream(out, ']'); } else { write_string(out, "null"); } }
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); }