Esempio n. 1
0
void set_regs_PC(Context * ctx, ContextAddress pc) {
    size_t i;
    uint8_t buf[8];
    RegisterDefinition * def = get_PC_definition(ctx);
    if (def == NULL) return;
    assert(def->size <= sizeof(buf));
    for (i = 0; i < def->size; i++) {
        buf[def->big_endian ? def->size - i - 1 : i] = (uint8_t)pc;
        pc = pc >> 8;
    }
    context_write_reg(ctx, def, 0, def->size, buf);
}
Esempio n. 2
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;
}
Esempio n. 3
0
static int get_stack_frame(Context * ctx, int frame, ContextAddress ip, IMAGEHLP_STACK_FRAME * stack_frame) {
    memset(stack_frame, 0, sizeof(IMAGEHLP_STACK_FRAME));
    if (frame == STACK_NO_FRAME) {
        stack_frame->InstructionOffset = ip;
    }
    else if (ctx->parent != NULL) {
        uint64_t v = 0;
        StackFrame * frame_info;
        if (get_frame_info(ctx, frame, &frame_info) < 0) return -1;
        if (read_reg_value(frame_info, get_PC_definition(ctx), &v) < 0) return -1;
        stack_frame->InstructionOffset = v;
    }
    return 0;
}
Esempio n. 4
0
static void generate_commands(void) {
    int i;
    RegisterRules * reg;
    RegisterDefinition * reg_def;

    reg = get_reg(&frame_regs, rules.return_address_register);
    if (reg->rule != 0) {
        reg_def = get_reg_by_id(rules.ctx, rules.return_address_register, &rules.reg_id_scope);
        generate_register_commands(reg, get_PC_definition(rules.ctx), reg_def);
    }
    for (i = 0; i < frame_regs.regs_cnt; i++) {
        reg = get_reg(&frame_regs, i);
        if (reg->rule == 0) continue;
        reg_def = get_reg_by_id(rules.ctx, i, &rules.reg_id_scope);
        generate_register_commands(reg, reg_def, reg_def);
    }

    trace_cmds_cnt = 0;
    switch (frame_regs.cfa_rule) {
    case RULE_OFFSET:
        reg_def = get_reg_by_id(rules.ctx, frame_regs.cfa_register, &rules.reg_id_scope);
        if (reg_def != NULL) {
            /* TriCore : PCXI needs to be decyphered so it will point ot the CSA
             * which is an area of the memory where registers were saved.
             */
            if ((rules.reg_id_scope.machine == EM_TRICORE) && (reg_def->dwarf_id == 41))
                add_command(SFT_CMD_RD_REG_PCXI_TRICORE)->args.reg = reg_def;
            else
                add_command(SFT_CMD_RD_REG)->args.reg = reg_def;
            if (frame_regs.cfa_offset != 0) {
                add_command(SFT_CMD_NUMBER)->args.num = frame_regs.cfa_offset;
                add_command(SFT_CMD_ADD);
            }
        }
        break;
    case RULE_EXPRESSION:
        add_dwarf_expression_commands(frame_regs.cfa_expression, frame_regs.cfa_offset);
        break;
    default:
        str_exception(ERR_INV_DWARF, "Invalid .debug_frame");
        break;
    }
    add_command_sequence(&dwarf_stack_trace_fp, NULL);
}
Esempio n. 5
0
static void write_context(OutputStream * out, char * id,
        Context * ctx, int frame, RegisterDefinition * reg_def) {

    assert(!ctx->exited);

    write_stream(out, '{');

    json_write_string(out, "ID");
    write_stream(out, ':');
    json_write_string(out, id);

    write_stream(out, ',');
    json_write_string(out, "ParentID");
    write_stream(out, ':');
    if (reg_def->parent != NULL) {
        json_write_string(out, register2id(ctx, frame, reg_def->parent));
    }
    else if (frame < 0 || is_top_frame(ctx, frame)) {
        json_write_string(out, ctx->id);
    }
    else {
        json_write_string(out, frame2id(ctx, frame));
    }

    write_stream(out, ',');
    json_write_string(out, "ProcessID");
    write_stream(out, ':');
    json_write_string(out, context_get_group(ctx, CONTEXT_GROUP_PROCESS)->id);

    write_stream(out, ',');
    json_write_string(out, "Name");
    write_stream(out, ':');
    json_write_string(out, reg_def->name);

    if (reg_def->size > 0) {
        write_stream(out, ',');
        json_write_string(out, "Size");
        write_stream(out, ':');
        json_write_long(out, reg_def->size);
    }

    if (reg_def->dwarf_id >= 0) {
        write_stream(out, ',');
        json_write_string(out, "DwarfID");
        write_stream(out, ':');
        json_write_long(out, reg_def->dwarf_id);
    }

    if (reg_def->eh_frame_id >= 0) {
        write_stream(out, ',');
        json_write_string(out, "EhFrameID");
        write_stream(out, ':');
        json_write_long(out, reg_def->eh_frame_id);
    }

    write_boolean_member(out, "BigEndian", reg_def->big_endian);
    write_boolean_member(out, "Float", reg_def->fp_value);
    write_boolean_member(out, "Readable", !reg_def->no_read);
    write_boolean_member(out, "Writeable", !reg_def->no_write);
    write_boolean_member(out, "ReadOnce", reg_def->read_once);
    write_boolean_member(out, "WriteOnce", reg_def->write_once);
    write_boolean_member(out, "Volatile", reg_def->volatile_value);
    write_boolean_member(out, "SideEffects", reg_def->side_effects);
    write_boolean_member(out, "LeftToRight", reg_def->left_to_right);

    if (reg_def->first_bit > 0) {
        write_stream(out, ',');
        json_write_string(out, "FirstBit");
        write_stream(out, ':');
        json_write_long(out, reg_def->first_bit);
    }

    if (reg_def->bits != NULL) {
        int i = 0;
        write_stream(out, ',');
        json_write_string(out, "Bits");
        write_stream(out, ':');
        write_stream(out, '[');
        while (reg_def->bits[i] >= 0) {
            if (i > 0) write_stream(out, ',');
            json_write_long(out, reg_def->bits[i++]);
        }
        write_stream(out, ']');
    }

    if (reg_def->values != NULL) {
        int i = 0;
        write_stream(out, ',');
        json_write_string(out, "Values");
        write_stream(out, ':');
        write_stream(out, '[');
        while (reg_def->values[i] != NULL) {
            NamedRegisterValue * v = reg_def->values[i++];
            if (i > 1) write_stream(out, ',');
            write_stream(out, '{');
            json_write_string(out, "Value");
            write_stream(out, ':');
            json_write_binary(out, v->value, reg_def->size);
            if (v->name != NULL) {
                write_stream(out, ',');
                json_write_string(out, "Name");
                write_stream(out, ':');
                json_write_string(out, v->name);
            }
            if (v->description != NULL) {
                write_stream(out, ',');
                json_write_string(out, "Description");
                write_stream(out, ':');
                json_write_string(out, v->description);
            }
            write_stream(out, '}');
        }
        write_stream(out, ']');
    }

    if (reg_def->memory_address > 0) {
        write_stream(out, ',');
        json_write_string(out, "MemoryAddress");
        write_stream(out, ':');
        json_write_uint64(out, reg_def->memory_address);
    }

    if (reg_def->memory_context != NULL) {
        write_stream(out, ',');
        json_write_string(out, "MemoryContext");
        write_stream(out, ':');
        json_write_string(out, reg_def->memory_context);
    }

    if (reg_def->role != NULL) {
        write_stream(out, ',');
        json_write_string(out, "Role");
        write_stream(out, ':');
        json_write_string(out, reg_def->role);
    }
    else if (reg_def == get_PC_definition(ctx)) {
        write_stream(out, ',');
        json_write_string(out, "Role");
        write_stream(out, ':');
        json_write_string(out, "PC");
    }

    if (reg_def->description != NULL) {
        write_stream(out, ',');
        json_write_string(out, "Description");
        write_stream(out, ':');
        json_write_string(out, reg_def->description);
    }

    if (reg_def->size > 0) {
        RegisterDefinition * parent_reg_def = NULL;
        parent_reg_def = reg_def->parent;
        while (parent_reg_def != NULL && parent_reg_def->size == 0) parent_reg_def = parent_reg_def->parent;
        if (parent_reg_def != NULL) {
            if (reg_def->offset >= parent_reg_def->offset &&
                reg_def->offset + reg_def->size <= parent_reg_def->offset + parent_reg_def->size) {
                write_stream(out, ',');
                json_write_string(out, "Offset");
                write_stream(out, ':');
                json_write_uint64(out, reg_def->offset - parent_reg_def->offset);
            }
        }
    }

    write_stream(out, '}');
    write_stream(out, 0);
}