Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2018-08-21 22:33:35 +0000
committerEugene Tarassov2018-08-21 22:33:35 +0000
commit21ccdf3832770c7f0aca9c765676e65db452501a (patch)
treebaf79bde790ad0b0232738642a83f45e10098da7
parente06d9d5a4d1f961bcdef97dd47a55dd5043fbf48 (diff)
downloadorg.eclipse.tcf.agent-21ccdf3832770c7f0aca9c765676e65db452501a.tar.gz
org.eclipse.tcf.agent-21ccdf3832770c7f0aca9c765676e65db452501a.tar.xz
org.eclipse.tcf.agent-21ccdf3832770c7f0aca9c765676e65db452501a.zip
TCF Agent: fixed handling of signed types in OP_GNU_deref_type
-rw-r--r--agent/tcf/services/vm.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/agent/tcf/services/vm.c b/agent/tcf/services/vm.c
index a499105b..af8d6fda 100644
--- a/agent/tcf/services/vm.c
+++ b/agent/tcf/services/vm.c
@@ -673,7 +673,45 @@ static void evaluate_expression(void) {
inv_dwarf("Unsupported type in OP_GNU_regval_type");
break;
case OP_GNU_deref_type:
- inv_dwarf("Unsupported type in OP_GNU_deref_type");
+ check_e_stack(1);
+ {
+ size_t mem_size = (size_t)read_u8leb128();
+ uint32_t fund_type = read_u4leb128();
+ uint32_t type_size = read_u4leb128();
+ switch (fund_type) {
+ case ATE_address:
+ case ATE_unsigned:
+ case ATE_unsigned_char:
+ case ATE_unsigned_fixed:
+ case ATE_UTF:
+ if (mem_size > type_size) mem_size = (size_t)type_size;
+ state->stk[state->stk_pos - 1] = read_memory(state->stk[state->stk_pos - 1], mem_size);
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
+ break;
+ case ATE_boolean:
+ if (mem_size > type_size) mem_size = (size_t)type_size;
+ state->stk[state->stk_pos - 1] = read_memory(state->stk[state->stk_pos - 1], mem_size);
+ if (state->type_stk[state->stk_pos - 1] != 0) state->type_stk[state->stk_pos - 1] = 1;
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
+ break;
+ case ATE_signed:
+ case ATE_signed_char:
+ case ATE_signed_fixed:
+ if (mem_size > type_size) mem_size = (size_t)type_size;
+ state->stk[state->stk_pos - 1] = read_memory(state->stk[state->stk_pos - 1], mem_size);
+ if (mem_size < 8) {
+ uint64_t sign = (uint64_t)1 << (mem_size * 8 - 1);
+ if (state->stk[state->stk_pos - 1] & sign) {
+ state->stk[state->stk_pos - 1] |= ~(sign - 1);
+ }
+ }
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_INTEGER;
+ break;
+ default:
+ inv_dwarf("Unsupported type in OP_GNU_deref_type");
+ break;
+ }
+ }
break;
case OP_GNU_convert:
inv_dwarf("Unsupported type in OP_GNU_convert");

Back to the top