TCF Agent: new property of expression value: bit stride
diff --git a/agent/tcf/services/expressions.c b/agent/tcf/services/expressions.c
index 351d844..f9e0e5a 100644
--- a/agent/tcf/services/expressions.c
+++ b/agent/tcf/services/expressions.c
@@ -186,6 +186,9 @@
v->sym_list = NULL;
v->size = (ContextAddress)size;
v->big_endian = big_endian;
+ v->binary_scale = 0;
+ v->decimal_scale = 0;
+ v->bit_stride = 0;
v->value = tmp_alloc(size);
if (data == NULL) memset(v->value, 0, size);
else memcpy(v->value, data, size);
@@ -205,8 +208,6 @@
case 8: buf.u64 = n; break;
default: assert(0);
}
- v->binary_scale = 0;
- v->decimal_scale = 0;
set_value(v, &buf, size, big_endian);
}
@@ -220,8 +221,6 @@
case 8: buf.d = n; break;
default: assert(0);
}
- v->binary_scale = 0;
- v->decimal_scale = 0;
set_value(v, &buf, size, big_endian);
}
@@ -1000,8 +999,31 @@
}
}
-static void set_value_scale(Value * v) {
- if (v->type != NULL && (v->type_class == TYPE_CLASS_CARDINAL || v->type_class == TYPE_CLASS_INTEGER)) {
+static void set_value_props(Value * v) {
+ v->bit_stride = 0;
+ v->binary_scale = 0;
+ v->decimal_scale = 0;
+ if (v->type == NULL) return;
+ if (v->type_class == TYPE_CLASS_ARRAY) {
+ Symbol * type = v->type;
+ for (;;) {
+ SymbolProperties props;
+ Symbol * next = NULL;
+ if (get_symbol_props(type, &props) < 0) {
+ error(errno, "Cannot get symbol properties");
+ }
+ if (props.bit_stride) {
+ v->bit_stride = props.bit_stride;
+ break;
+ }
+ if (get_symbol_type(type, &next) < 0) {
+ error(errno, "Cannot retrieve symbol type");
+ }
+ if (next == type) break;
+ type = next;
+ }
+ }
+ if (v->type_class == TYPE_CLASS_CARDINAL || v->type_class == TYPE_CLASS_INTEGER) {
Symbol * type = v->type;
for (;;) {
SymbolProperties props;
@@ -1072,7 +1094,7 @@
v->remote = 1;
}
v->constant = sym_class == SYM_CLASS_VALUE;
- set_value_scale(v);
+ set_value_props(v);
break;
case SYM_CLASS_FUNCTION:
{
@@ -2160,7 +2182,7 @@
if (get_symbol_size(v->type, &v->size) < 0) {
error(errno, "Cannot retrieve symbol size");
}
- set_value_scale(v);
+ set_value_props(v);
#else
error(ERR_UNSUPPORTED, "Symbols service not available");
#endif
@@ -2328,7 +2350,7 @@
if (sym_class == SYM_CLASS_REFERENCE && mode == MODE_NORMAL) {
check_hidden_redirection(v);
}
- set_value_scale(v);
+ set_value_props(v);
#else
error(ERR_UNSUPPORTED, "Symbols service not available");
#endif
@@ -2363,24 +2385,6 @@
}
}
-static unsigned get_bit_stride(Symbol * type) {
- for (;;) {
- Symbol * next = NULL;
- SymbolProperties props;
- memset(&props, 0, sizeof(props));
- if (get_symbol_props(type, &props) < 0) {
- error(errno, "Cannot get symbol properties");
- }
- if (props.bit_stride) return props.bit_stride;
- if (get_symbol_type(type, &next) < 0) {
- error(errno, "Cannot retrieve symbol type");
- }
- if (next == type) break;
- type = next;
- }
- return 0;
-}
-
static void op_index(int mode, Value * v) {
#if ENABLE_Symbols
Value i;
@@ -2432,7 +2436,6 @@
if (mode == MODE_NORMAL) {
int64_t index = to_int(mode, &i);
- unsigned bit_stride = 0;
ContextAddress byte_offs = 0;
ContextAddress bit_offs = 0;
int64_t lower_bound = 0;
@@ -2443,15 +2446,14 @@
if (index < lower_bound) {
error(ERR_INV_EXPRESSION, "Invalid index");
}
- bit_stride = get_bit_stride(v->type);
}
- if (bit_stride > 0) {
- bit_offs = (ContextAddress)(index - lower_bound) * bit_stride;
+ if (v->bit_stride > 0) {
+ bit_offs = (ContextAddress)(index - lower_bound) * v->bit_stride;
}
else {
byte_offs = (ContextAddress)(index - lower_bound) * size;
}
- if (v->remote && bit_stride == 0) {
+ if (v->remote && v->bit_stride == 0) {
assert(bit_offs == 0);
v->address += byte_offs;
}
@@ -2461,20 +2463,20 @@
}
load_value(v);
v->value = (char *)v->value + byte_offs;
- if (bit_stride > 0) {
+ if (v->bit_stride > 0) {
unsigned x;
uint8_t * buf = (uint8_t *)tmp_alloc_zero((size_t)size);
uint8_t * val = (uint8_t *)v->value;
- unsigned buf_offs = v->big_endian ? (unsigned)(size * 8 - bit_stride) : 0;
+ unsigned buf_offs = v->big_endian ? (unsigned)(size * 8 - v->bit_stride) : 0;
v->value = buf;
- for (x = 0; x < bit_stride; x++) {
+ for (x = 0; x < v->bit_stride; x++) {
unsigned y = (unsigned)(x + bit_offs);
unsigned z = (unsigned)(x + buf_offs);
if (val[y / 8] & bit_mask(v, y)) buf[z / 8] |= bit_mask(v, z);
}
if (type_class == TYPE_CLASS_INTEGER) {
/* Sign extension */
- bit_sign_extend(v, bit_stride);
+ bit_sign_extend(v, v->bit_stride);
}
}
}
@@ -2486,7 +2488,7 @@
v->size = size;
v->type = type;
v->type_class = type_class;
- set_value_scale(v);
+ set_value_props(v);
#else
error(ERR_UNSUPPORTED, "Symbols service not available");
#endif
@@ -2863,6 +2865,7 @@
else {
set_value(v, NULL, (size_t)v->size, 0);
}
+ set_value_props(v);
}
#else
@@ -4469,6 +4472,14 @@
cnt++;
}
#endif
+ if (value.bit_stride != 0) {
+ if (cnt > 0) write_stream(&c->out, ',');
+ json_write_string(&c->out, "BitStride");
+ write_stream(&c->out, ':');
+ json_write_ulong(&c->out, value.bit_stride);
+ cnt++;
+ }
+
if (value.binary_scale != 0) {
if (cnt > 0) write_stream(&c->out, ',');
json_write_string(&c->out, "BinaryScale");
diff --git a/agent/tcf/services/expressions.h b/agent/tcf/services/expressions.h
index cb8a6b6..64b8a8d 100644
--- a/agent/tcf/services/expressions.h
+++ b/agent/tcf/services/expressions.h
@@ -77,6 +77,7 @@
int function; /* 1 if the value represents a function */
int binary_scale; /* The exponent of the base two scale factor to be applied to the value */
int decimal_scale; /* The exponent of the base ten scale factor to be applied to the value */
+ unsigned bit_stride; /* if > 0, bit stride of the value */
Symbol ** sym_list; /* Symbol list, if applicable, NULL terminated */
Context * ctx; /* Debug context of the value */