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); }
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; }
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; }
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); }
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); }