Exemple #1
0
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);
}
Exemple #2
0
static void command_find_by_addr_cache_client(void * x) {
    CommandFindByAddrArgs * args = (CommandFindByAddrArgs *)x;
    Channel * c = cache_channel();
    Context * ctx = NULL;
    int frame = STACK_NO_FRAME;
    Symbol * sym = NULL;
    int err = 0;

    if (id2frame(args->id, &ctx, &frame) < 0) ctx = id2ctx(args->id);
    if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->id);
    else if (ctx->exited) err = ERR_ALREADY_EXITED;

    if (err == 0 && find_symbol_by_addr(ctx, frame, args->addr, &sym) < 0) err = errno;

    list_cnt = 0;
    if (err == 0) {
        list_add(sym);
        while (find_next_symbol(&sym) == 0) list_add(sym);
        if (get_error_code(errno) != ERR_SYM_NOT_FOUND) err = errno;
    }

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->token);
    write_errno(&c->out, err);
    write_symbol_list(&c->out);
    write_stream(&c->out, MARKER_EOM);
}
Exemple #3
0
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);
}
Exemple #4
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);
}
Exemple #5
0
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);
}
Exemple #6
0
static void command_reset_cache_client(void * x) {
    CommandResetArgs * args = (CommandResetArgs *)x;
    Channel * c = cache_channel();
    Context * ctx = id2ctx(args->id);
    OutputStream * out = &c->out;
    int err = 0;

    if (ctx == NULL) err = ERR_INV_CONTEXT;
    else if (ctx->exited) err = ERR_ALREADY_EXITED;

    if (!err) {
        Context * grp = get_reset_context(ctx);
        ResetInfo * rst = find_reset(grp, args->type);
        if (rst == NULL) err = set_errno(ERR_OTHER, "Unsupported reset type");
        else if (rst->reset(ctx, &args->params) < 0) err = errno;
    }

    cache_exit();

    while (args->params.list != NULL) {
        ResetParameter * p = args->params.list;
        args->params.list = p->next;
        loc_free(p->name);
        loc_free(p->value);
        loc_free(p);
    }

    write_stringz(out, "R");
    write_stringz(out, args->token);
    write_errno(out, err);
    write_stream(out, MARKER_EOM);
}
Exemple #7
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);
}
Exemple #8
0
static void command_get_address_info_cache_client(void * x) {
    int err = 0;
    Channel * c = cache_channel();
    CommandAddressInfo * args = (CommandAddressInfo *)x;
    Context * ctx = NULL;
    const char * isa = NULL;
    ContextAddress range_addr = 0;
    ContextAddress range_size = 0;
    ContextAddress plt = 0;

    ctx = id2ctx(args->id);
    if (ctx == NULL) err = ERR_INV_CONTEXT;
    if (!err && get_context_isa(ctx, args->addr,
        &isa, &range_addr, &range_size) < 0) err = errno;
    if (!err) plt = is_plt_section(ctx, args->addr);

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->token);
    write_errno(&c->out, err);
    if (!err) {
        write_stream(&c->out, '{');
        json_write_string(&c->out, "Addr");
        write_stream(&c->out, ':');
        json_write_uint64(&c->out, range_addr);
        write_stream(&c->out, ',');
        json_write_string(&c->out, "Size");
        write_stream(&c->out, ':');
        json_write_uint64(&c->out, range_size);
        if (isa != NULL) {
            write_stream(&c->out, ',');
            json_write_string(&c->out, "ISA");
            write_stream(&c->out, ':');
            json_write_string(&c->out, isa);
        }
        if (plt != 0) {
            write_stream(&c->out, ',');
            json_write_string(&c->out, "PLT");
            write_stream(&c->out, ':');
            json_write_uint64(&c->out, plt);
        }
        write_stream(&c->out, '}');
        write_stream(&c->out, 0);
    }
    else {
        write_stringz(&c->out, "null");
    }
    write_stream(&c->out, MARKER_EOM);
}
Exemple #9
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);
}
Exemple #10
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);
}
Exemple #11
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);
}
Exemple #12
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);
}
Exemple #13
0
static void command_list_cache_client(void * x) {
    CommandListArgs * args = (CommandListArgs *)x;
    Channel * c = cache_channel();
    Context * ctx = NULL;
    int frame = STACK_NO_FRAME;
    int err = 0;

    list_cnt = 0;

    if (id2frame(args->id, &ctx, &frame) < 0) ctx = id2ctx(args->id);
    if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->id);
    else if (ctx->exited) err = ERR_ALREADY_EXITED;

    if (err == 0 && enumerate_symbols(ctx, frame, list_callback, NULL) < 0) err = errno;

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->token);
    write_errno(&c->out, err);

    if (err == 0) {
        unsigned i = 0;
        write_stream(&c->out, '[');
        for (i = 0; i < list_cnt; i++) {
            if (i > 0) write_stream(&c->out, ',');
            json_write_string(&c->out, symbol2id(list_buf[i]));
        }
        write_stream(&c->out, ']');
        write_stream(&c->out, 0);
    }
    else {
        write_stringz(&c->out, "null");
    }

    write_stream(&c->out, MARKER_EOM);
}
Exemple #14
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);
    }
}
Exemple #15
0
static void command_find_frame_props_cache_client(void * x) {
    CommandFindFrameInfo * args = (CommandFindFrameInfo *)x;
    Channel * c = cache_channel();
    Context * ctx = NULL;
    StackTracingInfo * info = NULL;
    int err = 0;

    ctx = id2ctx(args->id);
    if (ctx == NULL) err = ERR_INV_CONTEXT;
    else if (get_stack_tracing_info(ctx, args->addr, &info) < 0) err = errno;

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->token);
    write_errno(&c->out, err);

    if (args->props) {
        unsigned cnt = 0;
        write_stream(&c->out, '{');

        if (info != NULL && info->size) {
            json_write_string(&c->out, "CodeAddr");
            write_stream(&c->out, ':');
            json_write_uint64(&c->out, info->addr);
            write_stream(&c->out, ',');
            json_write_string(&c->out, "CodeSize");
            write_stream(&c->out, ':');
            json_write_uint64(&c->out, info->size);
            cnt++;
        }

        if (info != NULL && info->fp != NULL) {
            if (cnt++ > 0) write_stream(&c->out, ',');
            json_write_string(&c->out, "FP");
            write_stream(&c->out, ':');
            write_commands(&c->out, ctx, info->fp->cmds, info->fp->cmds_cnt);
        }

        if (info != NULL && info->regs != NULL) {
            int i;
            if (cnt++ > 0) write_stream(&c->out, ',');
            json_write_string(&c->out, "Regs");
            write_stream(&c->out, ':');
            write_stream(&c->out, '{');
            for (i = 0; i < info->reg_cnt; i++) {
                if (i > 0) write_stream(&c->out, ',');
                json_write_string(&c->out, register2id(ctx, STACK_NO_FRAME, info->regs[i]->reg));
                write_stream(&c->out, ':');
                write_commands(&c->out, ctx, info->regs[i]->cmds, info->regs[i]->cmds_cnt);
            }
            write_stream(&c->out, '}');
        }

        if (info != NULL && info->subs != NULL) {
            int i;
            if (cnt++ > 0) write_stream(&c->out, ',');
            json_write_string(&c->out, "Inlined");
            write_stream(&c->out, ':');
            write_stream(&c->out, '[');
            for (i = 0; i < info->sub_cnt; i++) {
                if (i > 0) write_stream(&c->out, ',');
                write_inlined_subroutine_info(&c->out, info->subs[i]);
            }
            write_stream(&c->out, ']');
        }

        write_stream(&c->out, '}');
        write_stream(&c->out, 0);
    }
    else {
        /* Deprecated, use findFrameProps */

        json_write_uint64(&c->out, info ? info->addr : 0);
        write_stream(&c->out, 0);
        json_write_uint64(&c->out, info ? info->size : 0);
        write_stream(&c->out, 0);

        if (info == NULL || info->fp == NULL) write_string(&c->out, "null");
        else write_commands(&c->out, ctx, info->fp->cmds, info->fp->cmds_cnt);
        write_stream(&c->out, 0);

        if (info != NULL && info->regs != NULL) {
            int i;
            write_stream(&c->out, '{');
            for (i = 0; i < info->reg_cnt; i++) {
                if (i > 0) write_stream(&c->out, ',');
                json_write_string(&c->out, register2id(ctx, STACK_NO_FRAME, info->regs[i]->reg));
                write_stream(&c->out, ':');
                write_commands(&c->out, ctx, info->regs[i]->cmds, info->regs[i]->cmds_cnt);
            }
            write_stream(&c->out, '}');
        }
        else {
            write_string(&c->out, "null");
        }
        write_stream(&c->out, 0);
    }

    write_stream(&c->out, MARKER_EOM);
}
Exemple #16
0
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);
}
Exemple #17
0
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);
}
Exemple #18
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);
}
Exemple #19
0
static void command_get_sym_file_info_cache_client(void * x) {
    int err = 0;
    MemoryMap * client_map = NULL;
    MemoryMap * target_map = NULL;
    MemoryRegion * region = NULL;
    Channel * c = cache_channel();
    CommandSymFileInfo * args = (CommandSymFileInfo *)x;
    const char * sym_file = NULL;
    Context * ctx = NULL;
    int sym_error = 0;

    ctx = id2ctx(args->id);
    if (ctx == NULL) err = ERR_INV_CONTEXT;
    if (!err && memory_map_get(ctx, &client_map, &target_map) < 0) err = errno;

    if (!err) {
        unsigned i;
        for (i = 0; i < client_map->region_cnt; i++) {
            MemoryRegion * r = client_map->regions + i;
            if (r->addr <= args->addr && r->addr + r->size > args->addr) region = r;
        }
        if (region == NULL) {
            for (i = 0; i < target_map->region_cnt; i++) {
                MemoryRegion * r = target_map->regions + i;
                if (r->addr <= args->addr && r->addr + r->size > args->addr) region = r;
            }
        }

#if ENABLE_ELF
        /* TODO: need a generic way to support ELF program headers in getSymFileInfo command */
        if (region == NULL) {
            static MemoryMap map;
            extern int elf_get_map(Context * ctx, ContextAddress addr0, ContextAddress addr1, MemoryMap * map);
            if (elf_get_map(ctx, args->addr, args->addr, &map) == 0) {
                for (i = 0; i < map.region_cnt; i++) {
                    MemoryRegion * r = map.regions + i;
                    if (r->addr <= args->addr && r->addr + r->size > args->addr) region = r;
                }
            }
        }
#endif

        sym_file = get_symbol_file_name(ctx, region);
        sym_error = errno;
    }

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->token);
    write_errno(&c->out, err);
    if (region != NULL) {
        write_stream(&c->out, '{');
        json_write_string(&c->out, "Addr");
        write_stream(&c->out, ':');
        json_write_uint64(&c->out, region->addr);
        write_stream(&c->out, ',');
        json_write_string(&c->out, "Size");
        write_stream(&c->out, ':');
        json_write_uint64(&c->out, region->size);
        if (sym_file != NULL) {
            write_stream(&c->out, ',');
            json_write_string(&c->out, "FileName");
            write_stream(&c->out, ':');
            json_write_string(&c->out, sym_file);
        }
        if (sym_error != 0) {
            write_stream(&c->out, ',');
            json_write_string(&c->out, "FileError");
            write_stream(&c->out, ':');
            write_error_object(&c->out, sym_error);
        }
        write_stream(&c->out, '}');
        write_stream(&c->out, 0);
    }
    else {
        write_stringz(&c->out, "null");
    }
    write_stream(&c->out, MARKER_EOM);
}