Example #1
0
void
init_traps(void) {

	/*
	 * Fill the exception area with branch instructions so
	 * if we get something we don't expect, the kernel will hardcrash.
	 */
	set_trap(SH_EXC_GENERAL, __exc_unexpected, 0x00);
	set_trap(SH_EXC_TLBMISS, __exc_unexpected, 0x00);
	set_trap(SH_EXC_INTR, __exc_unexpected, 0x00);

    install_traps();
}
static void handle_channel_msg(void * x) {
    Trap trap;
    ChannelNP * c = (ChannelNP *)x;
    int has_msg;

    assert(is_dispatch_thread());
    assert(c->magic == CHANNEL_MAGIC);
    assert(c->ibuf.handling_msg == HandleMsgTriggered);
    assert(c->ibuf.message_count);

    has_msg = ibuf_start_message(&c->ibuf);
    if (has_msg <= 0) {
        if (has_msg < 0 && c->chan.state != ChannelStateDisconnected) {
            trace(LOG_PROTOCOL, "Socket is shutdown by remote peer, channel %#lx %s", c, c->chan.peer_name);
            channel_close(&c->chan);
        }
    }
    else if (set_trap(&trap)) {
        if (c->chan.receive) {
            c->chan.receive(&c->chan);
        }
        else {
            handle_protocol_message(&c->chan);
            assert(c->out_bin_block == NULL);
        }
        clear_trap(&trap);
    }
    else {
        trace(LOG_ALWAYS, "Exception in message handler: %s", errno_to_str(trap.error));
        send_eof_and_close(&c->chan, trap.error);
    }
}
void virtual_stream_create(const char * type, const char * context_id, size_t buf_len, unsigned access,
        VirtualStreamCallBack * callback, void * callback_args, VirtualStream ** res) {
    LINK * l;
    VirtualStream * stream = loc_alloc_zero(sizeof(VirtualStream));

    buf_len++;
    list_init(&stream->clients);
    strncpy(stream->type, type, sizeof(stream->type) - 1);
    stream->magic = STREAM_MAGIC;
    stream->id = id_cnt++;
    stream->access = access;
    stream->callback = callback;
    stream->callback_args = callback_args;
    stream->ref_cnt = 1;
    stream->buf = loc_alloc(buf_len);
    stream->buf_len = buf_len;
    for (l = subscriptions.next; l != &subscriptions; l = l->next) {
        Subscription * h = all2subscription(l);
        if (strcmp(type, h->type) == 0) {
            Trap trap;
            create_client(stream, h->channel);
            if (set_trap(&trap)) {
                send_event_stream_created(&h->channel->out, stream, context_id);
                clear_trap(&trap);
            }
            else {
                trace(LOG_ALWAYS, "Exception sending stream created event: %d %s",
                      trap.error, errno_to_str(trap.error));
            }
        }
    }
    list_add_first(&stream->link_all, &streams);
    *res = stream;
}
DWARFCache * get_dwarf_cache(ELF_File * File) {
    DWARFCache * Cache = (DWARFCache *)File->dwarf_dt_cache;
    if (Cache == NULL) {
        Trap trap;
        if (!sCloseListenerOK) {
            elf_add_close_listener(free_dwarf_cache);
            sCloseListenerOK = 1;
        }
        sCache = Cache = (DWARFCache *)(File->dwarf_dt_cache = loc_alloc_zero(sizeof(DWARFCache)));
        sCache->magic = SYM_CACHE_MAGIC;
        sCache->mFile = File;
        sCache->mObjectHash = loc_alloc_zero(sizeof(ObjectInfo *) * OBJ_HASH_SIZE);
        if (set_trap(&trap)) {
            dio_LoadAbbrevTable(File);
            load_symbol_tables();
            load_debug_sections();
            clear_trap(&trap);
        }
        else {
            sCache->mErrorCode = trap.error;
            strncpy(sCache->mErrorMsg, trap.msg, sizeof(sCache->mErrorMsg) - 1);
        }
        sCache = NULL;
    }
    if (Cache->mErrorCode) str_exception(Cache->mErrorCode, Cache->mErrorMsg);
    return Cache;
}
static void subscribe_cb(Channel * c, void * x, int error) {
    Trap trap;
    PortConnection * conn = (PortConnection *)x;
    PortAttribute * attr = conn->server->redir_info->attrs;
    OutputStream * out = &conn->server->channel->out;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    /* Ignore error for subscribe since we may already have subscribed for this channel */

    conn->pending = protocol_send_command(conn->server->channel, "PortForward",
            "create", portcreate_cb, conn);
    write_stream(out, '{');
    json_write_string(out, "ID");
    write_stream(out, ':');
    json_write_string(out, conn->id);
    write_stream(out, ',');
    while (attr != NULL) {
        json_write_string(out, attr->name);
        write_stream(out, ':');
        write_string(out, attr->value);
        attr = attr->next;
    }
    write_stream(out, '}');
    write_stream(out, MARKER_EOA);
    write_stream(out, MARKER_EOM);
}
Example #6
0
int ini_server(const char * url, Protocol * p, TCFBroadcastGroup * b) {
    ChannelServer * serv = NULL;
    PeerServer * ps = NULL;
    Trap trap;

    if (!set_trap(&trap)) {
        bcg = NULL;
        proto = NULL;
        if (ps != NULL) peer_server_free(ps);
        errno = trap.error;
        return -1;
    }

    bcg = b;
    proto = p;
    ps = channel_peer_from_url(url);
    if (ps == NULL) str_exception(ERR_OTHER, "Invalid server URL");
    peer_server_addprop(ps, loc_strdup("Name"), loc_strdup(PROXY_NAME));
    peer_server_addprop(ps, loc_strdup("Proxy"), loc_strdup(""));
    SERVER_ADDPROP_HOOK;
    serv = channel_server(ps);
    if (serv == NULL) exception(errno);
    serv->new_conn = channel_new_connection;

    clear_trap(&trap);
    add_channel_redirection_listener(channel_redirection_listener);
    return 0;
}
static void delete_config_done(Channel *c, void *client_data, int error) {
    PortConnection * conn = (PortConnection *) client_data;
    Trap trap;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    if (!conn->auto_connect_stream) {
        protocol_send_command(conn->server->channel, "Streams", "disconnect", disconnect_stream_done, conn);
        json_write_string(&conn->server->channel->out, conn->out_stream_id);
        write_stream(&conn->server->channel->out, MARKER_EOA);
        write_stream(&conn->server->channel->out, MARKER_EOM);
    }
    else {
        loc_free(conn->out_stream_id);
        conn->out_stream_id = NULL;
        loc_free(conn->in_stream_id);
        conn->in_stream_id = NULL;
        port_unlock(conn);
        port_connection_close(conn);
    }
}
Example #8
0
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, &reg_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 load_debug_sections(void) {
    Trap trap;
    unsigned idx;
    ELF_File * File = sCache->mFile;

    memset(&trap, 0, sizeof(trap));
    sSymbolTableLen = sCache->mSymbolTableLen;
    sObjectList = NULL;
    sObjectListTail = NULL;
    sCompUnitsMax = 0;

    for (idx = 1; idx < File->section_cnt; idx++) {
        ELF_Section * sec = File->sections + idx;
        if (sec->size == 0) continue;
        if (sec->name == NULL) continue;
        if (strcmp(sec->name, ".debug") == 0 || strcmp(sec->name, ".debug_info") == 0) {
            sDebugSection = sec;
            sParentObject = NULL;
            sPrevSibling = NULL;
            dio_EnterDebugSection(NULL, sec, 0);
            if (set_trap(&trap)) {
                while (dio_GetPos() < sec->size) {
                    dio_ReadUnit(&sUnitDesc, entry_callback);
                    sCompUnit->mDesc = sUnitDesc;
                }
                clear_trap(&trap);
            }
            dio_ExitSection();
            sParentObject = NULL;
            sPrevSibling = NULL;
            sCompUnit = NULL;
            sDebugSection = NULL;
            if (trap.error) break;
        }
        else if (strcmp(sec->name, ".debug_ranges") == 0) {
            sCache->mDebugRanges = sec;
        }
        else if (strcmp(sec->name, ".debug_aranges") == 0) {
            sCache->mDebugARanges = sec;
        }
        else if (strcmp(sec->name, ".debug_line") == 0) {
            sCache->mDebugLine = sec;
        }
        else if (strcmp(sec->name, ".debug_loc") == 0) {
            sCache->mDebugLoc = sec;
        }
    }

    if (sObjectList == NULL) {
        loc_free(sCache->mObjectHash);
        sCache->mObjectHash = NULL;
    }
    sCache->mObjectList = sObjectList;
    sSymbolTableLen = 0;
    sObjectList = NULL;
    sObjectListTail = NULL;
    sCompUnitsMax = 0;
    if (trap.error) str_exception(trap.error, trap.msg);
}
static void getcapabilities_cb(Channel * c, void * x, int error) {
    Trap trap;
    PortConnection * conn = (PortConnection *)x;
    PortAttribute * attr = conn->server->redir_info->attrs;
    OutputStream * out = &conn->server->channel->out;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_read_struct(&c->inp, read_getcapabilities_struct, (void *)conn);
            json_test_char(&c->inp, MARKER_EOA);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    if (error) {
        connect_port_callback(conn, error);
    } else {
        if (conn->auto_connect_stream) {
            conn->pending = protocol_send_command(conn->server->channel, "PortForward",
                    "create", portcreate_cb, conn);
            write_stream(out, '{');
            json_write_string(out, "ID");
            write_stream(out, ':');
            json_write_string(out, conn->id);
            while (attr != NULL) {
                write_stream(out, ',');
                if (strcmp(attr->name,  "RemotePort") == 0) {
                    json_write_string(out, "Port");
                }
                else {
                    json_write_string(out, attr->name);
                }
                write_stream(out, ':');
                write_string(out, attr->value);
                attr = attr->next;
            }
            if (conn->auto_connect_stream) {
                write_stream(out, ',');
                json_write_string(out, "AutoConnect");
                write_stream(out, ':');
                json_write_boolean(out, 1);
            }
            write_stream(out, '}');
            write_stream(out, MARKER_EOA);
            write_stream(out, MARKER_EOM);
        }
        else {
            conn->pending = protocol_send_command(conn->server->channel, "Streams", "subscribe",
                    subscribe_cb, conn);
            json_write_string(out, "PortForward");
            write_stream(out, MARKER_EOA);
            write_stream(out, MARKER_EOM);
        }
    }
}
Example #11
0
submap::submap() : ter(), frn(), trp(), rad(),
    active_item_count(0), field_count(0), turn_last_touched(0), temperature(0) {
    for (int x = 0; x < SEEX; x++) {
        for (int y = 0; y < SEEY; y++) {
            ter[x][y] = t_null;
            set_furn(x, y, f_null);
            set_trap(x, y, tr_null);
            set_radiation(x, y, 0);
        }
    }
}
Example #12
0
static void run_cache_client(int retry) {
    Trap trap;
    unsigned i;
    unsigned id = current_client.id;
    void * args_copy = NULL;

    assert(id != 0);
    current_cache = NULL;
    cache_miss_cnt = 0;
    def_channel = NULL;
    if (current_client.args_copy) args_copy = current_client.args;
    for (i = 0; i < listeners_cnt; i++) listeners[i](retry ? CTLE_RETRY : CTLE_START);
    if (set_trap(&trap)) {
        current_client.client(current_client.args);
        clear_trap(&trap);
        assert(current_client.id == 0);
        assert(cache_miss_cnt == 0);
    }
    else if (id != current_client.id) {
        trace(LOG_ALWAYS, "Unhandled exception in data cache client: %s", errno_to_str(trap.error));
        assert(current_client.id == 0);
        assert(cache_miss_cnt == 0);
    }
    else {
        if (get_error_code(trap.error) != ERR_CACHE_MISS || cache_miss_cnt == 0 || current_cache == NULL) {
            trace(LOG_ALWAYS, "Unhandled exception in data cache client: %s", errno_to_str(trap.error));
            for (i = 0; i < listeners_cnt; i++) listeners[i](CTLE_COMMIT);
        }
        else {
            AbstractCache * cache = current_cache;
            if (cache->wait_list_cnt >= cache->wait_list_max) {
                cache->wait_list_max += 8;
                cache->wait_list_buf = (WaitingCacheClient *)loc_realloc(cache->wait_list_buf, cache->wait_list_max * sizeof(WaitingCacheClient));
            }
            if (current_client.args != NULL && !current_client.args_copy) {
                void * mem = loc_alloc(current_client.args_size);
                memcpy(mem, current_client.args, current_client.args_size);
                current_client.args = mem;
                current_client.args_copy = 1;
            }
            if (cache->wait_list_cnt == 0) list_add_last(&cache->link, &cache_list);
            if (current_client.channel != NULL) channel_lock_with_msg(current_client.channel, channel_lock_msg);
            cache->wait_list_buf[cache->wait_list_cnt++] = current_client;
            for (i = 0; i < listeners_cnt; i++) listeners[i](CTLE_ABORT);
            args_copy = NULL;
        }
        memset(&current_client, 0, sizeof(current_client));
        current_cache = NULL;
        cache_miss_cnt = 0;
        def_channel = NULL;
    }
    if (args_copy != NULL) loc_free(args_copy);
}
Example #13
0
static LocationExpressionState * evaluate_location(Context * ctx, int frame, LocationInfo * loc_info) {
    Trap trap;
    StackFrame * frame_info = NULL;
    LocationExpressionState * state = NULL;
    static uint64_t args[] = { 0, 0 };

    if (frame != STACK_NO_FRAME && get_frame_info(ctx, frame, &frame_info) < 0) return NULL;
    if (!set_trap(&trap)) return NULL;
    state = evaluate_location_expression(ctx, frame_info,
        loc_info->value_cmds.cmds, loc_info->value_cmds.cnt, args, loc_info->args_cnt);
    clear_trap(&trap);
    return state;
}
Example #14
0
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);
}
Example #15
0
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, &reg_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);
}
/*H:230 While we're here, dealing with delivering traps and interrupts to the
 * Guest, we might as well complete the picture: how the Guest tells us where
 * it wants them to go.  This would be simple, except making traps fast
 * requires some tricks.
 *
 * We saw the Guest setting Interrupt Descriptor Table (IDT) entries with the
 * LHCALL_LOAD_IDT_ENTRY hypercall before: that comes here. */
void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int num, u32 lo, u32 hi)
{
	/* Guest never handles: NMI, doublefault, spurious interrupt or
	 * hypercall.  We ignore when it tries to set them. */
	if (num == 2 || num == 8 || num == 15 || num == LGUEST_TRAP_ENTRY)
		return;

	/* Mark the IDT as changed: next time the Guest runs we'll know we have
	 * to copy this again. */
	cpu->changed |= CHANGED_IDT;

	/* Check that the Guest doesn't try to step outside the bounds. */
	if (num >= ARRAY_SIZE(cpu->arch.idt))
		kill_guest(cpu, "Setting idt entry %u", num);
	else
		set_trap(cpu, &cpu->arch.idt[num], num, lo, hi);
}
Example #17
0
static void terminal_exited(void * args) {
    Terminal * term = (Terminal *)args;
    Trap trap;

    if (set_trap(&trap)) {
        send_event_terminal_exited(&term->bcg->out, term);
        clear_trap(&trap);
    }
    else {
        trace(LOG_ALWAYS, "Exception sending terminal exited event: %d %s",
            trap.error, errno_to_str(trap.error));
    }

    list_remove(&term->link);
    channel_unlock_with_msg(term->channel, TERMINALS);
    loc_free(term);
}
static void getconfig_cb(Channel * c, void * x, int error) {
    Trap trap;
    PortConnection * conn = (PortConnection *)x;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_read_struct(&c->inp, read_getconfig_struct, (void *)conn);
            json_test_char(&c->inp, MARKER_EOA);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    connect_port_callback(conn, error);
}
Example #19
0
File: cache.c Project: eswartz/emul
static void run_cache_client(void) {
    Trap trap;

    cache_miss_cnt = 0;
    client_exited = 0;
    if (set_trap(&trap)) {
        current_client.client(current_client.args);
        clear_trap(&trap);
        assert(cache_miss_cnt == 0);
        assert(client_exited);
    }
    else if (get_error_code(trap.error) != ERR_CACHE_MISS || client_exited || cache_miss_cnt == 0) {
        trace(LOG_ALWAYS, "Unhandled exception in data cache client: %d %s", trap.error, errno_to_str(trap.error));
    }
    if (cache_miss_cnt == 0 && current_client.args_copy) loc_free(current_client.args);
    memset(&current_client, 0, sizeof(current_client));
    cache_miss_cnt = 0;
    client_exited = 0;
}
Example #20
0
static void delete_write_request(WriteRequest * r, int error) {
    Channel * c = r->client->channel;
    Trap trap;

    if (set_trap(&trap)) {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, r->token);
        write_errno(&c->out, error);
        write_stream(&c->out, MARKER_EOM);
        clear_trap(&trap);
    }
    else {
        trace(LOG_ALWAYS, "Exception handling pending stream write command: %d %s",
              trap.error, errno_to_str(trap.error));
    }
    list_remove(&r->link_client);
    loc_free(r->data);
    loc_free(r);
}
Example #21
0
static void append_format_parameter(char * type, char * style, char * param) {
    /* Note: 'param' is UTF-8 encoded JSON text */
    char str[64];
    if (param != NULL && (*param == '"' || strcmp(type, "number") == 0)) {
        Trap trap;
        ByteArrayInputStream buf;
        InputStream * inp = create_byte_array_input_stream(&buf, param, strlen(param));
        if (set_trap(&trap)) {
            if (*param == '"') {
                char * x = json_read_alloc_string(inp);
                if (x != NULL) {
                    char * s = x;
                    while (*s) {
                        realloc_msg_buf();
                        msg_buf[msg_buf_len++] = *s++;
                    }
                    loc_free(x);
                }
                param = NULL;
            }
            else {
                double x = json_read_double(inp);
                if (strcmp(style, "percent") == 0) {
                    snprintf(str, sizeof(str), "%ld%%", (long)(x * 100));
                }
                else if (strcmp(style, "integer") == 0) {
                    snprintf(str, sizeof(str), "%ld", (long)x);
                }
                else {
                    snprintf(str, sizeof(str), "%g", x);
                }
                param = str;
            }
            clear_trap(&trap);
        }
    }
    if (param != NULL) {
        while (*param) {
            realloc_msg_buf();
            msg_buf[msg_buf_len++] = *param++;
        }
    }
}
static void write_stream_done(Channel *c, void *client_data, int error) {
    Trap trap;
    PortConnection * conn = (PortConnection *) client_data;;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    assert (conn->pending_write_request <= MAX_STREAM_WRITE && conn->pending_write_request > 0);
    if (conn->pending_write_request == MAX_STREAM_WRITE) {
        send_packet_callback(conn, error);
    }
    conn->pending_write_request--;
}
Example #23
0
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);
}
Example #24
0
static void delete_config_done(Channel *c, void *client_data, int error) {
    PortConnection * conn = (PortConnection *) client_data;
    Trap trap;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    loc_free(conn->out_stream_id);
    conn->out_stream_id = NULL;
    loc_free(conn->in_stream_id);
    conn->in_stream_id = NULL;
    port_unlock(conn);
    port_connection_close(conn);
}
Example #25
0
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, &reg_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);
}
Example #26
0
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);
}
Example #27
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);
}
Example #28
0
static ContextAddress get_module_id(Context * ctx, ELF_File * module) {
    ELF_File * exe_file = NULL;
    ContextAddress addr = elf_get_debug_structure_address(ctx, &exe_file);
    size_t word_size = exe_file && exe_file->elf64 ? 8 : 4;
    Trap trap;

    if (addr == 0 || exe_file == NULL) str_exception(ERR_OTHER, "Cannot find loader debug data");
    if (set_trap(&trap)) {
        ContextAddress r_map = 0;
        ContextAddress r_brk = 0;
        ContextAddress mod_id = 0;
        if (elf_read_memory_word(ctx, exe_file, addr + word_size * 1, &r_map) < 0) exception(errno);
        if (elf_read_memory_word(ctx, exe_file, addr + word_size * 2, &r_brk) < 0) exception(errno);
        if (r_map != 0 && r_brk != 0) mod_id = find_module(ctx, exe_file, module, r_map, r_brk);
        clear_trap(&trap);
        if (mod_id) return mod_id;
    }
    else {
        str_exception(trap.error, "Cannot access target ELF loader data");
    }
    str_exception(ERR_OTHER, "Cannot get TLS module ID");
    return 0;
}
static void delete_client(StreamClient * client) {
    VirtualStream * stream = client->stream;
    Trap trap;
    LINK * n;

    assert(stream->ref_cnt > 0);
    if (set_trap(&trap)) {
        send_event_stream_disposed(&client->channel->out, stream);
        clear_trap(&trap);
    }
    else {
        trace(LOG_ALWAYS, "Exception sending stream deleted event: %d %s",
              trap.error, errno_to_str(trap.error));
    }
    list_remove(&client->link_hash);
    list_remove(&client->link_stream);
    list_remove(&client->link_all);
    for (n = client->read_requests.next; n != &client->read_requests;) {
        ReadRequest * r = client2read_request(n);
        n = n->next;
        delete_read_request(r);
    }
    for (n = client->write_requests.next; n != &client->write_requests;) {
        WriteRequest * r = client2write_request(n);
        n = n->next;
        delete_write_request(r, ERR_COMMAND_CANCELLED);
    }
    loc_free(client);
    if (--stream->ref_cnt == 0) {
        assert(list_is_empty(&stream->clients));
        assert(stream->deleted);
        post_event(delete_stream, stream);
    }
    else if (stream->access & VS_ENABLE_REMOTE_READ) {
        advance_stream_buffer(stream);
    }
}
static void portcreate_cb(Channel * c, void * x, int error) {
    Trap trap;
    PortConnection * conn = (PortConnection *)x;

    if (set_trap(&trap)) {
        if (!error) {
            error = read_errno(&c->inp);
            json_test_char(&c->inp, MARKER_EOM);
        }
        clear_trap(&trap);
    }
    else {
        error = trap.error;
    }
    if (error) {
        connect_port_callback(conn, error);
    } else {
        conn->pending = protocol_send_command(conn->server->channel, "PortForward",
                "getConfig", getconfig_cb, conn);
        json_write_string(&conn->server->channel->out, conn->id);
        write_stream(&conn->server->channel->out, MARKER_EOA);
        write_stream(&conn->server->channel->out, MARKER_EOM);
    }
}