Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2012-01-03 17:39:06 +0000
committerEugene Tarassov2012-01-03 17:39:06 +0000
commit8786550ce7810b8ae0b74b0cb1c6beda74ac61bf (patch)
tree5088b7b787580e92e1facbd71aa160f9ba20ed14
parent565cc0e30e57881522f9b61d67549df1771d2d08 (diff)
downloadorg.eclipse.tcf.agent-8786550ce7810b8ae0b74b0cb1c6beda74ac61bf.tar.gz
org.eclipse.tcf.agent-8786550ce7810b8ae0b74b0cb1c6beda74ac61bf.tar.xz
org.eclipse.tcf.agent-8786550ce7810b8ae0b74b0cb1c6beda74ac61bf.zip
TCF Agent: more support for remote execution of DWARF expressions (not complete yet).
-rw-r--r--agent/tcf/services/dwarfecomp.c51
-rw-r--r--agent/tcf/services/vm.c2
2 files changed, 51 insertions, 2 deletions
diff --git a/agent/tcf/services/dwarfecomp.c b/agent/tcf/services/dwarfecomp.c
index 675ee1a0..e1c87d1b 100644
--- a/agent/tcf/services/dwarfecomp.c
+++ b/agent/tcf/services/dwarfecomp.c
@@ -29,9 +29,19 @@
#include <tcf/services/dwarf.h>
#include <tcf/services/dwarfecomp.h>
+typedef struct JumpInfo {
+ U1_T op;
+ I2_T offs;
+ size_t size;
+ size_t src_pos;
+ size_t dst_pos;
+ struct JumpInfo * next;
+} JumpInfo;
+
static U1_T * buf = NULL;
static size_t buf_pos = 0;
static size_t buf_max = 0;
+static JumpInfo * jumps = NULL;
static DWARFExpressionInfo * expr = NULL;
static size_t expr_pos = 0;
static Context * expr_ctx = NULL;
@@ -222,9 +232,20 @@ static void op_implicit_pointer(U1_T op) {
}
}
+static void adjust_jumps(void) {
+ JumpInfo * i = jumps;
+ while (i != NULL) {
+ if (i->op == OP_bra || i->op == OP_skip) {
+ str_exception(ERR_OTHER, "OP_skip/OP_bra not supported yet");
+ }
+ i = i->next;
+ }
+}
+
static void add_expression(DWARFExpressionInfo * info) {
DWARFExpressionInfo * org_expr = expr;
size_t org_expr_pos = expr_pos;
+ JumpInfo * org_jumps = jumps;
if (expr != NULL && info->code_size) {
if (expr->code_size) {
@@ -248,7 +269,10 @@ static void add_expression(DWARFExpressionInfo * info) {
expr = info;
expr_pos = 0;
+ jumps = NULL;
while (expr_pos < info->expr_size) {
+ size_t op_src_pos = expr_pos;
+ size_t op_dst_pos = buf_pos;
U1_T op = info->expr_addr[expr_pos];
switch (op) {
case OP_const1u:
@@ -318,7 +342,18 @@ static void add_expression(DWARFExpressionInfo * info) {
break;
case OP_bra:
case OP_skip:
- str_exception(ERR_UNSUPPORTED, "OP_bra/OP_skip not supported yet");
+ {
+ uint16_t x0 = info->expr_addr[expr_pos + 1];
+ uint16_t x1 = info->expr_addr[expr_pos + 2];
+ JumpInfo * i = (JumpInfo *)tmp_alloc_zero(sizeof(JumpInfo));
+ i->op = op;
+ i->offs = expr->unit->mFile->big_endian ? (x0 << 8) | x1 : x0 | (x1 << 8);
+ i->src_pos = expr_pos;
+ i->dst_pos = buf_pos;
+ i->next = jumps;
+ jumps = i;
+ copy(3);
+ }
break;
case OP_bregx:
case OP_bit_piece:
@@ -362,9 +397,21 @@ static void add_expression(DWARFExpressionInfo * info) {
expr_pos++;
break;
}
+ if (buf_pos - op_dst_pos != expr_pos - op_src_pos) {
+ JumpInfo * i = (JumpInfo *)tmp_alloc_zero(sizeof(JumpInfo));
+ assert(op != OP_bra && op != OP_skip);
+ i->op = op;
+ i->offs = (I2_T)(buf_pos - op_dst_pos) - (I2_T)(expr_pos - op_src_pos);
+ i->src_pos = op_src_pos;
+ i->dst_pos = op_dst_pos;
+ i->next = jumps;
+ jumps = i;
+ }
}
+ adjust_jumps();
expr = org_expr;
expr_pos = org_expr_pos;
+ jumps = org_jumps;
}
void dwarf_transform_expression(Context * ctx, ContextAddress ip, DWARFExpressionInfo * info) {
@@ -374,12 +421,14 @@ void dwarf_transform_expression(Context * ctx, ContextAddress ip, DWARFExpressio
expr_ctx = ctx;
expr_ip = ip;
expr = NULL;
+ jumps = NULL;
add_expression(info);
info->expr_addr = buf;
info->expr_size = buf_pos;
buf_pos = 0;
buf_max = 0;
buf = NULL;
+ jumps = NULL;
expr = NULL;
expr_pos = 0;
expr_ctx = NULL;
diff --git a/agent/tcf/services/vm.c b/agent/tcf/services/vm.c
index 07405c7c..2f6dbf02 100644
--- a/agent/tcf/services/vm.c
+++ b/agent/tcf/services/vm.c
@@ -385,7 +385,7 @@ static void evaluate_expression(void) {
case OP_bra:
check_e_stack(1);
{
- unsigned offs = (int16_t)read_u2();
+ size_t offs = (int16_t)read_u2();
if (state->stk[state->stk_pos - 1]) {
code_pos += offs;
if (code_pos > code_len) inv_dwarf("Invalid command");

Back to the top