Example #1
0
static int arm_read_reg(unsigned n, uint32_t * res) {
    unsigned i;
    uint8_t buf[4];
    *res = 0;
    assert(regs_index[n].size == 4);
    assert(!regs_index[n].big_endian);
    if (context_read_reg(arm_ctx, regs_index + n, 0, 4, buf) < 0) return -1;
    for (i = 0; i < 4; i++) *res |= (uint32_t)buf[i] << (i * 8);
    return 0;
}
Example #2
0
static int read_reg(Context *ctx, RegisterDefinition * def, size_t size, ContextAddress * addr) {
    size_t i;
    uint8_t buf[8];
    uint64_t n = 0;
    *addr = 0;
    assert(!def->big_endian);
    assert(size <= def->size);
    assert(size <= sizeof(buf));
    if (context_read_reg(ctx, def, 0, size, buf) < 0) return -1;
    for (i = 0; i < size; i++) n |= (uint64_t)buf[i] << (i * 8);
    *addr = (ContextAddress)n;
    return 0;
}
Example #3
0
ContextAddress get_regs_PC(Context * ctx) {
    size_t i;
    uint8_t buf[8];
    ContextAddress pc = 0;
    RegisterDefinition * def = get_PC_definition(ctx);
    if (def == NULL) return 0;
    assert(def->size <= sizeof(buf));
    if (context_read_reg(ctx, def, 0, def->size, buf) < 0) return 0;
    for (i = 0; i < def->size; i++) {
        pc = pc << 8;
        pc |= buf[def->big_endian ? i : def->size - i - 1];
    }
    return pc;
}
Example #4
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);
}
Example #5
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 #6
0
ContextAddress get_tls_address(Context * ctx, ELF_File * file) {
    ContextAddress mod_tls_addr = 0;
    RegisterIdScope reg_id_scope;

    memset(&reg_id_scope, 0, sizeof(reg_id_scope));
    reg_id_scope.machine = file->machine;
    reg_id_scope.os_abi = file->os_abi;
    reg_id_scope.elf64 = file->elf64;
    reg_id_scope.big_endian = file->big_endian;
    reg_id_scope.id_type = REGNUM_DWARF;

    switch (file->machine) {
    case EM_X86_64:
    {
        uint8_t buf[8];
        ContextAddress tcb_addr = 0;
        ContextAddress vdt_addr = 0;
        ContextAddress mod_id = 0;
        RegisterDefinition * reg_def = get_reg_by_id(ctx, 58, &reg_id_scope);
        if (reg_def == NULL) exception(errno);
        if (context_read_reg(ctx, reg_def, 0, reg_def->size, buf) < 0)
            str_exception(errno, "Cannot read TCB base register");
        tcb_addr = to_address(buf, reg_def->size, reg_def->big_endian);
        if (elf_read_memory_word(ctx, file, tcb_addr + 8, &vdt_addr) < 0)
            str_exception(errno, "Cannot read TCB");
        mod_id = get_module_id(ctx, file);
        if (elf_read_memory_word(ctx, file, vdt_addr + mod_id * 16, &mod_tls_addr) < 0)
            str_exception(errno, "Cannot read VDT");
        if (mod_tls_addr == 0 || mod_tls_addr == ~(ContextAddress)0)
            str_exception(errno, "Thread local storage is not allocated yet");
    }
    break;
    default:
        str_fmt_exception(ERR_INV_CONTEXT,
                          "Thread local storage access is not supported yet for machine type %d",
                          file->machine);
    }
    return mod_tls_addr;
}