Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/agent/tcf
diff options
context:
space:
mode:
authorEugene Tarassov2017-08-03 20:51:52 +0000
committerEugene Tarassov2017-08-03 20:51:52 +0000
commit0775cd4e668e999b8885705de543ef2cc92fae06 (patch)
tree5d0e7bf96256e0afd86887cc7a363d0474b02c95 /agent/tcf
parentdb59380a4e891144b6e6c2f9cccf177537523aa3 (diff)
downloadorg.eclipse.tcf.agent-0775cd4e668e999b8885705de543ef2cc92fae06.tar.gz
org.eclipse.tcf.agent-0775cd4e668e999b8885705de543ef2cc92fae06.tar.xz
org.eclipse.tcf.agent-0775cd4e668e999b8885705de543ef2cc92fae06.zip
TCF Agent: fixed handling of large registers (> 8 bytes) saved in a stack frame
Diffstat (limited to 'agent/tcf')
-rw-r--r--agent/tcf/framework/cpudefs.c28
-rw-r--r--agent/tcf/services/dwarfframe.c2
-rw-r--r--agent/tcf/services/stacktrace.c27
3 files changed, 43 insertions, 14 deletions
diff --git a/agent/tcf/framework/cpudefs.c b/agent/tcf/framework/cpudefs.c
index 6e4afd8f..4dd55191 100644
--- a/agent/tcf/framework/cpudefs.c
+++ b/agent/tcf/framework/cpudefs.c
@@ -322,14 +322,30 @@ LocationExpressionState * evaluate_location_expression(Context * ctx, StackFrame
size_t j;
size_t size = cmd->args.mem.size;
uint64_t n = 0;
- uint8_t buf[8];
- assert(size <= sizeof(buf));
- if (context_read_mem(ctx, (ContextAddress)stk[stk_pos - 1], buf, size) < 0) exception(errno);
- for (j = 0; j < size; j++) {
- n = (n << 8) | buf[cmd->args.mem.big_endian ? j : size - j - 1];
+ if (size <= sizeof(n)) {
+ uint8_t buf[8];
+ if (context_read_mem(ctx, (ContextAddress)stk[stk_pos - 1], buf, size) < 0) exception(errno);
+ for (j = 0; j < size; j++) {
+ n = (n << 8) | buf[cmd->args.mem.big_endian ? j : size - j - 1];
+ }
+ stk[stk_pos - 1] = n;
+ }
+ else if (state->pieces_cnt == 0 && i + 1 == cmd_cnt && stk_pos == 1) {
+ LocationPiece * piece = NULL;
+ if (state->pieces_cnt >= state->pieces_max) {
+ state->pieces_max += 4;
+ state->pieces = (LocationPiece *)tmp_realloc(state->pieces, state->pieces_max * sizeof(LocationPiece));
+ }
+ piece = state->pieces + state->pieces_cnt++;
+ memset(piece, 0, sizeof(LocationPiece));
+ piece->addr = (ContextAddress)stk[stk_pos - 1];
+ piece->size = size;
+ stk_pos--;
+ }
+ else {
+ exception(ERR_INV_DATA_SIZE);
}
- stk[stk_pos - 1] = n;
}
break;
case SFT_CMD_WR_MEM:
diff --git a/agent/tcf/services/dwarfframe.c b/agent/tcf/services/dwarfframe.c
index 8b80820a..34c76f6b 100644
--- a/agent/tcf/services/dwarfframe.c
+++ b/agent/tcf/services/dwarfframe.c
@@ -834,7 +834,6 @@ static void generate_register_commands(RegisterRules * reg, RegisterDefinition *
if (reg->rule == RULE_OFFSET) {
LocationExpressionCommand * cmd = add_command(SFT_CMD_RD_MEM);
cmd->args.mem.size = dst_reg_def->size;
- if (cmd->args.mem.size > rules.address_size) cmd->args.mem.size = rules.address_size;
cmd->args.mem.big_endian = rules.reg_id_scope.big_endian;
}
break;
@@ -855,7 +854,6 @@ static void generate_register_commands(RegisterRules * reg, RegisterDefinition *
if (reg->rule == RULE_EXPRESSION) {
LocationExpressionCommand * cmd = add_command(SFT_CMD_RD_MEM);
cmd->args.mem.size = dst_reg_def->size;
- if (cmd->args.mem.size > rules.address_size) cmd->args.mem.size = rules.address_size;
cmd->args.mem.big_endian = rules.reg_id_scope.big_endian;
}
break;
diff --git a/agent/tcf/services/stacktrace.c b/agent/tcf/services/stacktrace.c
index c8353678..5bb71b8b 100644
--- a/agent/tcf/services/stacktrace.c
+++ b/agent/tcf/services/stacktrace.c
@@ -165,11 +165,12 @@ int get_next_stack_frame(StackFrame * frame, StackFrame * down) {
}
down->ctx = ctx;
for (i = 0; i < info->reg_cnt; i++) {
- int ok = 0;
- uint64_t v = 0;
+ RegisterDefinition * reg_def = info->regs[i]->reg;
+ uint8_t * buf = NULL;
+ size_t size = 0;
Trap trap_reg;
#if ENABLE_StackRegisterLocations
- if (write_reg_location(down, info->regs[i]->reg, info->regs[i]->cmds, info->regs[i]->cmds_cnt) == 0) {
+ if (write_reg_location(down, reg_def, info->regs[i]->cmds, info->regs[i]->cmds_cnt) == 0) {
down->has_reg_data = 1;
continue;
}
@@ -178,12 +179,26 @@ int get_next_stack_frame(StackFrame * frame, StackFrame * down) {
/* If a saved register value cannot be evaluated - ignore it */
state = evaluate_location_expression(ctx, frame, info->regs[i]->cmds, info->regs[i]->cmds_cnt, NULL, 0);
if (state->stk_pos == 1) {
- v = state->stk[0];
- ok = 1;
+ unsigned j;
+ uint64_t v = state->stk[0];
+ buf = (uint8_t *)tmp_alloc_zero(reg_def->size);
+ for (j = 0; j < reg_def->size; j++) {
+ buf[reg_def->big_endian ? reg_def->size - j - 1 : j] = (uint8_t)v;
+ v = v >> 8;
+ }
+ size = reg_def->size;
+ }
+ else if (state->stk_pos == 0 && state->pieces_cnt > 0) {
+ read_location_pieces(state->ctx, state->stack_frame,
+ state->pieces, state->pieces_cnt, state->reg_id_scope.big_endian, (void **)&buf, &size);
}
clear_trap(&trap_reg);
}
- if (ok && write_reg_value(down, info->regs[i]->reg, v) < 0) exception(errno);
+ if (buf != NULL && size > 0) {
+ if (size > reg_def->size) size = reg_def->size;
+ if (write_reg_bytes(down, reg_def, 0, size, buf) < 0) exception(errno);
+ down->has_reg_data = 1;
+ }
}
clear_trap(&trap);
frame->is_walked = 1;

Back to the top