Пример #1
0
static void safe_event_disassemble(void * x) {
    DisassembleCmdArgs * args = (DisassembleCmdArgs *)x;
    if (!is_channel_closed(args->c)) {
        cache_enter(disassemble_cache_client, args->c, args, sizeof(DisassembleCmdArgs));
    }
    channel_unlock(args->c);
    loc_free(args);
}
Пример #2
0
void cache_enter(CacheClient * client, Channel * channel, void * args, size_t args_size) {
    assert(is_dispatch_thread());
    assert(client != NULL);
    assert(channel != NULL);
    assert(!is_channel_closed(channel));
    assert(current_client.client == NULL);
    current_client.client = client;
    current_client.channel = channel;
    current_client.args = args;
    current_client.args_size = args_size;
    current_client.args_copy = 0;
    run_cache_client();
}
static void port_connection_open(PortServer * server, int fd) {
    PortConnection * conn;

    if (server->channel == NULL || is_channel_closed(server->channel)) {
        closesocket(fd);
        return;
    }

    conn = loc_alloc_zero(sizeof(PortConnection));

    if (conn == NULL) {
        closesocket(fd);
    }
    else {
        int idx = 0;
        conn->recv_req.client_data = conn;
        conn->recv_req.done = done_recv_request;
        conn->recv_req.type = server->is_udp ? AsyncReqRecvFrom : AsyncReqRecv;
        conn->recv_req.u.sio.sock = fd;
        conn->recv_req.u.sio.flags = 0;
        conn->recv_req.u.sio.bufp = conn->inbuf;
        conn->recv_req.u.sio.bufsz = IN_BUF_SIZE;
        conn->recv_req.u.sio.addr = &server->client_addr;
        conn->recv_req.u.sio.addrlen = sizeof(conn->server->client_addr);

        conn->send_req.client_data = conn;
        conn->send_req.done = done_send_request;
        conn->send_req.type = server->is_udp ? AsyncReqSendTo : AsyncReqSend;
        conn->send_req.u.sio.sock = fd;
        conn->send_req.u.sio.flags = 0;

        conn->send_in_progress = -1;    /* no send request in progress */
        for (idx = 0; idx < MAX_STREAM_READ; idx++) {
            conn->read_info[idx].idx = idx;
            conn->read_info[idx].conn = conn;
        }

        conn->fd = fd;
        conn->server = server;
        conn->next = server->list;
        server->list = conn;

        connect_port(conn);
    }
}
Пример #4
0
static void connect_done(void * args, int error, Channel * c2) {
    ConnectInfo * info = (ConnectInfo *)args;
    Channel * c1 = info->c1;

    if (!is_channel_closed(c1)) {
        assert(c1->state == ChannelStateRedirectReceived);
        if (error) {
            fprintf(stderr, "cannot connect to peer: %s\n", dest_url);
            channel_close(c1);
        }
        else {
            proxy_create(c1, c2);
        }
    }
    else if (!error) {
        channel_close(c2);
    }
    channel_unlock(c1);
    peer_server_free(info->ps);
    loc_free(info);
}
Пример #5
0
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);
    }
}
Пример #6
0
static void safe_memory_fill(void * parm) {
    MemoryCommandArgs * args = (MemoryCommandArgs *)parm;
    Channel * c = args->c;
    Context * ctx = args->ctx;

    if (!is_channel_closed(c)) {
        Trap trap;
        if (set_trap(&trap)) {
            InputStream * inp = &c->inp;
            OutputStream * out = &c->out;
            char * token = args->token;
            ContextAddress addr0 = args->addr;
            ContextAddress addr = args->addr;
            unsigned long size = args->size;
            MemoryErrorInfo err_info;
            MemoryFillBuffer buf;
            char * tmp = NULL;
            int err = 0;

            memset(&err_info, 0, sizeof(err_info));
            if (ctx->exiting || ctx->exited) err = ERR_ALREADY_EXITED;

            memset(&buf, 0, sizeof(buf));
            buf.buf = (char *)tmp_alloc(buf.max = BUF_SIZE);

            if (err) json_skip_object(inp);
            else json_read_array(inp, read_memory_fill_array_cb, &buf);
            json_test_char(inp, MARKER_EOA);
            json_test_char(inp, MARKER_EOM);

            while (err == 0 && buf.pos < size && buf.pos <= buf.max / 2) {
                if (buf.pos == 0) {
                    buf.buf[buf.pos++] = 0;
                }
                else {
                    memcpy(buf.buf + buf.pos, buf.buf, buf.pos);
                    buf.pos *= 2;
                }
            }

            while (err == 0 && addr < addr0 + size) {
                /* Note: context_write_mem() modifies buffer contents */
                unsigned wr = (unsigned)(addr0 + size - addr);
                if (tmp == NULL) tmp = (char *)tmp_alloc(buf.pos);
                if (wr > buf.pos) wr = buf.pos;
                /* TODO: word size, mode */
                memcpy(tmp, buf.buf, wr);
                if (context_write_mem(ctx, addr, tmp, wr) < 0) {
                    err = errno;
#if ENABLE_ExtendedMemoryErrorReports
                    context_get_mem_error_info(&err_info);
#endif
                }
                else {
                    addr += wr;
                }
            }

            send_event_memory_changed(ctx, addr0, size);

            write_stringz(out, "R");
            write_stringz(out, token);
            write_errno(out, err);
            if (err == 0) {
                write_stringz(out, "null");
            }
            else {
                write_ranges(out, addr0, (int)(addr - addr0), BYTE_CANNOT_WRITE, &err_info);
            }
            write_stream(out, MARKER_EOM);
            clear_trap(&trap);
        }
        else {
            trace(LOG_ALWAYS, "Exception in Memory.fill: %s", errno_to_str(trap.error));
            channel_close(c);
        }
    }
    channel_unlock(c);
    context_unlock(ctx);
    loc_free(args);
}
Пример #7
0
static void safe_memory_get(void * parm) {
    MemoryCommandArgs * args = (MemoryCommandArgs *)parm;
    Channel * c = args->c;
    Context * ctx = args->ctx;

    if (!is_channel_closed(c)) {
        Trap trap;
        if (set_trap(&trap)) {
            OutputStream * out = &args->c->out;
            char * token = args->token;
            ContextAddress addr0 = args->addr;
            ContextAddress addr = args->addr;
            unsigned long size = args->size;
            unsigned long pos = 0;
            char buf[BUF_SIZE];
            int err = 0;
            MemoryErrorInfo err_info;
            JsonWriteBinaryState state;

            memset(&err_info, 0, sizeof(err_info));
            if (ctx->exiting || ctx->exited) err = ERR_ALREADY_EXITED;

            write_stringz(out, "R");
            write_stringz(out, token);

            json_write_binary_start(&state, out, size);
            while (pos < size) {
                int rd = size - pos;
                if (rd > BUF_SIZE) rd = BUF_SIZE;
                /* TODO: word size, mode */
                memset(buf, 0, rd);
                if (err == 0) {
                    if (context_read_mem(ctx, addr, buf, rd) < 0) {
                        err = errno;
#if ENABLE_ExtendedMemoryErrorReports
                        context_get_mem_error_info(&err_info);
#endif
                    }
                    else {
                        addr += rd;
                    }
                }
                json_write_binary_data(&state, buf, rd);
                pos += rd;
            }
            json_write_binary_end(&state);
            write_stream(out, 0);

            write_errno(out, err);
            if (err == 0) {
                write_stringz(out, "null");
            }
            else {
                write_ranges(out, addr0, (int)(addr - addr0), BYTE_CANNOT_READ, &err_info);
            }
            write_stream(out, MARKER_EOM);
            clear_trap(&trap);
        }
        else {
            trace(LOG_ALWAYS, "Exception in Memory.get: %s", errno_to_str(trap.error));
            channel_close(c);
        }
    }
    channel_unlock(c);
    context_unlock(ctx);
    loc_free(args);
}
Пример #8
0
static void safe_memory_set(void * parm) {
    MemoryCommandArgs * args = (MemoryCommandArgs *)parm;
    Channel * c = args->c;
    Context * ctx = args->ctx;

    if (!is_channel_closed(c)) {
        Trap trap;
        if (set_trap(&trap)) {
            InputStream * inp = &c->inp;
            OutputStream * out = &c->out;
            char * token = args->token;
            ContextAddress addr0 = args->addr;
            ContextAddress addr = args->addr;
            unsigned long size = 0;
            char buf[BUF_SIZE];
            int err = 0;
            MemoryErrorInfo err_info;
            JsonReadBinaryState state;

            memset(&err_info, 0, sizeof(err_info));
            if (ctx->exiting || ctx->exited) err = ERR_ALREADY_EXITED;

            json_read_binary_start(&state, inp);
            for (;;) {
                int rd = json_read_binary_data(&state, buf, sizeof(buf));
                if (rd == 0) break;
                if (err == 0) {
                    /* TODO: word size, mode */
                    if (context_write_mem(ctx, addr, buf, rd) < 0) {
                        err = errno;
#if ENABLE_ExtendedMemoryErrorReports
                        context_get_mem_error_info(&err_info);
#endif
                    }
                    else {
                        addr += rd;
                    }
                }
                size += rd;
            }
            json_read_binary_end(&state);
            json_test_char(inp, MARKER_EOA);
            json_test_char(inp, MARKER_EOM);

            send_event_memory_changed(ctx, addr0, size);

            write_stringz(out, "R");
            write_stringz(out, token);
            write_errno(out, err);
            if (err == 0) {
                write_stringz(out, "null");
            }
            else {
                write_ranges(out, addr0, (int)(addr - addr0), BYTE_CANNOT_WRITE, &err_info);
            }
            write_stream(out, MARKER_EOM);
            clear_trap(&trap);
        }
        else {
            trace(LOG_ALWAYS, "Exception in Memory.set: %s", errno_to_str(trap.error));
            channel_close(c);
        }
    }
    channel_unlock(c);
    context_unlock(ctx);
    loc_free(args);
}
Пример #9
0
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);
}