Bug 464689 - Support for AT_bit_stride - fixed sign extension
diff --git a/agent/tcf/services/expressions.c b/agent/tcf/services/expressions.c
index dd93ea7..255d37e 100644
--- a/agent/tcf/services/expressions.c
+++ b/agent/tcf/services/expressions.c
@@ -2332,6 +2332,7 @@
Value i;
ContextAddress size = 0;
Symbol * type = NULL;
+ int type_class = 0;
expression(mode, &i);
if (mode == MODE_SKIP) return;
@@ -2345,6 +2346,12 @@
if (get_symbol_base_type(v->type, &type) < 0) {
error(errno, "Cannot get array element type");
}
+ if (type == NULL) {
+ error(ERR_INV_EXPRESSION, "Array element type is unknown");
+ }
+ if (get_symbol_type_class(type, &type_class) < 0) {
+ error(errno, "Cannot get type class of the array element");
+ }
if (v->type_class == TYPE_CLASS_POINTER) {
if (v->loc && v->loc->pieces_cnt == 1 && v->loc->pieces->implicit_pointer) {
v->loc->pieces->implicit_pointer--;
@@ -2412,6 +2419,16 @@
unsigned y = (unsigned)(x + bit_offs);
if (val[y / 8] & (1 << (y % 8))) buf[x / 8] |= 1 << (x % 8);
}
+ if (type_class == TYPE_CLASS_INTEGER) {
+ /* Sign extension */
+ unsigned sign_offs = props.bit_stride - 1;
+ int sign = (buf[sign_offs / 8] & (1 << (sign_offs % 8))) != 0;
+ if (sign) {
+ for (x = props.bit_stride; x < size * 8; x++) {
+ buf[x / 8] |= 1 << (x % 8);
+ }
+ }
+ }
}
}
}
@@ -2421,9 +2438,7 @@
v->loc = NULL;
v->size = size;
v->type = type;
- if (get_symbol_type_class(type, &v->type_class) < 0) {
- error(errno, "Cannot retrieve symbol type class");
- }
+ v->type_class = type_class;
set_value_scale(v);
#else
error(ERR_UNSUPPORTED, "Symbols service not available");