diff --git a/framework/common.h b/framework/common.h index ab87b16..dad88f2 100644 --- a/framework/common.h +++ b/framework/common.h @@ -8,24 +8,35 @@ #include "logger/log.h" #include "linkedlist.h" +typedef enum { + DWARF_TYPE_INVALID = 0, + DWARF_TYPE_UNSIGNED, + DWARF_TYPE_SIGNED, + DWARF_TYPE_ADDRESS, + DWARF_TYPE_GENERIC +} dwarf_value_type; + typedef struct __dwarf_value : public SC_ListNode { __dwarf_value(uint32_t s) { size = s; value = (char*)malloc(s); + type = DWARF_TYPE_INVALID; } - __dwarf_value(char*v, uint32_t s) + __dwarf_value(char*v, uint32_t s, dwarf_value_type t) { size = s; value = (char*)malloc(s); memcpy(value, v, s); + type = t; } __dwarf_value() { value = NULL; size = 0; + type = DWARF_TYPE_INVALID; } ~__dwarf_value() @@ -37,8 +48,69 @@ typedef struct __dwarf_value : public SC_ListNode { } } - char* value; - uint32_t size; + void replace(void* v, uint32_t s, dwarf_value_type t) + { + if(value) { + free(value); + size = 0; + type = DWARF_TYPE_INVALID; + } + + value = (char*)malloc(s); + memcpy(value, v, s); + size = s; + type = t; + } + + bool get_uint(uint64_t v) + { + switch (size) { + case 1: + v = (uint8_t)*((uint8_t*)value); + break; + case 2: + v = (uint16_t)*((uint16_t*)value); + break; + case 4: + v = (uint32_t)*((uint32_t*)value); + break; + case 8: + v = (uint64_t)*((uint64_t*)value); + break; + default: + return false; + break; + } + + return true; + } + + bool get_int(int64_t v) + { + switch (size) { + case 1: + v = (int8_t)*((int8_t*)value); + break; + case 2: + v = (int16_t)*((int16_t*)value); + break; + case 4: + v = (int32_t)*((int32_t*)value); + break; + case 8: + v = (int64_t)*((int64_t*)value); + break; + default: + return false; + break; + } + + return true; + } + + char* value; + uint32_t size; + dwarf_value_type type; } dwarf_value; typedef struct __dwarf_stack : public SC_ListHead { @@ -49,8 +121,8 @@ typedef struct __dwarf_stack : public SC_ListHead { } } - void push(char* v, uint32_t s) { - dwarf_value* value = new dwarf_value(v, s); + void push(void* v, uint32_t s, dwarf_value_type t) { + dwarf_value* value = new dwarf_value((char*)v, s, t); InsertFirst(value); } @@ -66,6 +138,15 @@ typedef struct __dwarf_stack : public SC_ListHead { return value; } + dwarf_value* get(uint32_t idx = 0) { + dwarf_value* value = NULL; + for(value = (dwarf_value*)First(); value && idx; value = (dwarf_value*)Next(value)) { + idx--; + } + + return value; + } + } dwarf_stack; typedef struct __pst_context { diff --git a/framework/dwarf_operations.cpp b/framework/dwarf_operations.cpp index f233fa6..854577a 100644 --- a/framework/dwarf_operations.cpp +++ b/framework/dwarf_operations.cpp @@ -7,15 +7,554 @@ #include #include "dwarf_operations.h" +#include "common.h" + +bool dw_op_notimpl(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + ctx->log(SEVERITY_ERROR, "0x%lX => %s(0x%lX, 0x%lX) operation is not implemented", map->op_num, map->op_name, op1, op2); + return false; +} bool dw_op_addr(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) { + // The DW_OP_addr operation has a single operand that encodes a machine + // address and whose size is the size of an address on the target machine. + ctx->stack.push(&op1, sizeof(op1), DWARF_TYPE_ADDRESS); return true; } +bool dw_op_deref(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_ OP_deref operation pops the top stack entry and treats it as an address. + // The popped value must have an integral type. The value retrieved from that address is pushed, and has the generic type. + // The size of the data retrieved from the dereferenced address is the size of an address on the target machine. + dwarf_value* value = ctx->stack.pop(); + if(value) { + uint64_t v = *((uint64_t*)value->value); + ctx->stack.push(&v, sizeof(v), DWARF_TYPE_GENERIC); + + return true; + } + + return false; +} + +bool dw_op_const_x_u(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // DW_OP_const1u, DW_OP_const2u, DW_OP_const4u, DW_OP_const8u. The single operand of a DW_OP_constu operation provides a 1, 2, 4, or 8-byte unsigned integer constant, respectively. + uint8_t size = 0; + switch (map->op_num) { + case DW_OP_const1u: + size = 1; + break; + case DW_OP_const2u: + size = 2; + break; + case DW_OP_const4u: + size = 4; + break; + case DW_OP_const8u: + size = 1; + break; + default: + return false; + } + + ctx->stack.push(&op1, size, DWARF_TYPE_UNSIGNED); + + return true; +} + +bool dw_op_const_x_s(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // DW_OP_const1s, DW_OP_const2s, DW_OP_const4s, DW_OP_const8s. The single operand of a DW_OP_consts operation provides a 1, 2, 4, or 8-byte signed integer constant, respectively. + uint8_t size = 0; + switch (map->op_num) { + case DW_OP_const1u: + size = 1; + break; + case DW_OP_const2u: + size = 2; + break; + case DW_OP_const4u: + size = 4; + break; + case DW_OP_const8u: + size = 1; + break; + default: + return false; + } + + ctx->stack.push(&op1, size, DWARF_TYPE_SIGNED); + + return true; +} + +bool dw_op_constu(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The single operand of the DW_OP_constu operation provides an unsigned LEB128 integer constant. + uint64_t value = decode_uleb128((unsigned char*)&op1); + ctx->stack.push(&value, sizeof(value), DWARF_TYPE_UNSIGNED); + return true; +} + +bool dw_op_consts(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The single operand of the DW_OP_consts operation provides a signed LEB128 integer constant. + uint64_t value = decode_sleb128((unsigned char*)&op1); + ctx->stack.push(&value, sizeof(value), DWARF_TYPE_SIGNED); + return true; +} + +bool dw_op_dup(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_dup operation duplicates the value (including its type identifier) at the top of the stack. + dwarf_value* value = ctx->stack.get(); + ctx->stack.push(value->value, value->size, value->type); + + return true; +} + +bool dw_op_drop(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_drop operation pops the value (including its type identifier) at the top of the stack. + dwarf_value* value = ctx->stack.pop(); + free(value); + + return true; +} + +bool dw_op_over(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_over operation duplicates the entry currently second in the stack at the top of the stack. + // This is equivalent to a DW_OP_pick operation, with index 1. + + dwarf_value* value = ctx->stack.get(1); + ctx->stack.push(value->value, value->size, value->type); + + return true; +} + +bool dw_op_pick(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The single operand of the DW_OP_pick operation provides a 1-byte index. + // A copy of the stack entry (including its type identifier) with the specified index (0 through 255, inclusive) is pushed onto the stack. + + dwarf_value* value = ctx->stack.get(op1); + if(value) { + ctx->stack.push(value->value, value->size, value->type); + return true; + } + + return false; +} + +bool dw_op_swap(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_swap operation swaps the top two stack entries. The entry at the top of the stack (including its type identifier) becomes the second stack + // entry, and the second entry (including its type identifier) becomes the top of the stack. + + dwarf_value* value1 = ctx->stack.pop(); + dwarf_value* value2 = ctx->stack.pop(); + if(value1 && value2) { + ctx->stack.push(value1); + ctx->stack.push(value2); + return true; + } + + return false; +} + +bool dw_op_rot(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_rot operation rotates the first three stack entries. + // The entry at the top of the stack (including its type identifier) becomes the third stack entry, + // the second entry (including its type identifier) becomes the top of the stack, + // and the third entry (including its type identifier) becomes the second entry + + dwarf_value* value1 = ctx->stack.pop(); + dwarf_value* value2 = ctx->stack.pop(); + dwarf_value* value3 = ctx->stack.pop(); + if(value1 && value2 && value3) { + ctx->stack.push(value1); + ctx->stack.push(value3); + ctx->stack.push(value2); + return true; + } + + return false; +} + +bool dw_op_abs(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_abs operation pops the top stack entry, interprets it as a signed value and pushes its absolute value. + // If the absolute value cannot be represented, the result is undefined. + + dwarf_value* value = ctx->stack.get(); + if(value) { + uint64_t v; + if(!value->get_int(v)) { + ctx->log(SEVERITY_ERROR, "Wrong %d size of stack value", value->size); + return false; + } + + value->replace(&v, value->size, DWARF_TYPE_SIGNED); + } + + return false; +} + +bool dw_op_and(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_and operation pops the top two stack values, performs a bitwise and operation on the two, and pushes the result. + + dwarf_value* value1 = ctx->stack.pop(); + dwarf_value* value2 = ctx->stack.pop(); + if(value1 && value2) { + if(value1->type != value2->type) { + ctx->log(SEVERITY_ERROR, "Different types of two stack values for operation: %s(%d, %d)", map->op_name, value1->type, value2->type); + return false; + } + uint64_t v1 = 0, v2 = 0; + if(!value1->get_uint(v1)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 1st stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + if(!value2->get_uint(v2)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 2nd stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + uint64_t res = v1 & v2; + ctx->stack.push(&res, value1->size, value1->type); + return true; + } + + return false; +} + +bool dw_op_div(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_div operation pops the top two stack values, divides the former second entry by the former top of the stack using signed division, and pushes the result. + + dwarf_value* value1 = ctx->stack.pop(); + dwarf_value* value2 = ctx->stack.pop(); + if(value1 && value2) { + if(value1->type != value2->type) { + ctx->log(SEVERITY_ERROR, "Different types of two stack values for operation: %s(%d, %d)", map->op_name, value1->type, value2->type); + return false; + } + int64_t v1 = 0, v2 = 0; + if(!value1->get_int(v1)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 1st stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + if(!value2->get_int(v2)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 2nd stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + int64_t res = v2 / v1; + ctx->stack.push(&res, value1->size, value1->type); + return true; + } + + return false; +} + +bool dw_op_minus(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_minus operation pops the top two stack values, subtracts the former top of the stack from the former second entry, and pushes the result. + + dwarf_value* value1 = ctx->stack.pop(); + dwarf_value* value2 = ctx->stack.pop(); + if(value1 && value2) { + if(value1->type != value2->type) { + ctx->log(SEVERITY_ERROR, "Different types of two stack values for operation: %s(%d, %d)", map->op_name, value1->type, value2->type); + return false; + } + int64_t v1 = 0, v2 = 0; + if(!value1->get_int(v1)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 1st stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + if(!value2->get_int(v2)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 2nd stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + int64_t res = v2 - v1; + ctx->stack.push(&res, value1->size, value1->type); + return true; + } + + return false; +} + +bool dw_op_mod(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_mod operation pops the top two stack values and pushes the result of the calculation: former second stack entry modulo the former top of the stack. + + dwarf_value* value1 = ctx->stack.pop(); + dwarf_value* value2 = ctx->stack.pop(); + if(value1 && value2) { + if(value1->type != value2->type) { + ctx->log(SEVERITY_ERROR, "Different types of two stack values for operation: %s(%d, %d)", map->op_name, value1->type, value2->type); + return false; + } + int64_t v1 = 0, v2 = 0; + if(!value1->get_int(v1)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 1st stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + if(!value2->get_int(v2)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 2nd stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + int64_t res = v2 % v1; + ctx->stack.push(&res, value1->size, value1->type); + return true; + } + + return false; +} + +bool dw_op_mul(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_mul operation pops the top two stack entries, multiplies them together, and pushes the result. + + dwarf_value* value1 = ctx->stack.pop(); + dwarf_value* value2 = ctx->stack.pop(); + if(value1 && value2) { + if(value1->type != value2->type) { + ctx->log(SEVERITY_ERROR, "Different types of two stack values for operation: %s(%d, %d)", map->op_name, value1->type, value2->type); + return false; + } + int64_t v1 = 0, v2 = 0; + if(!value1->get_int(v1)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 1st stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + if(!value2->get_int(v2)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 2nd stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + int64_t res = v2 * v1; + ctx->stack.push(&res, value1->size, value1->type); + return true; + } + + return false; +} + +bool dw_op_neg(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_neg operation pops the top stack entry, interprets it as a signed value and pushes its negation. + // If the negation cannot be represented, the result is undefined. + + dwarf_value* value = ctx->stack.get(); + if(value) { + int64_t v = 0; + if(!value->get_int(v)) { + ctx->log(SEVERITY_ERROR, "Wrong size of stack value for operation %s(%d)", map->op_name, value->size); + return false; + } + v *= -1; + + switch (value->size) { + case 1: { + int8_t vv = (int8_t)v; + value->replace(&vv, sizeof(vv), value->type); + break; + } + case 2: { + int16_t vv = (int16_t)v; + value->replace(&vv, sizeof(vv), value->type); + break; + } + case 4: { + int32_t vv = (int32_t)v; + value->replace(&vv, sizeof(vv), value->type); + break; + } + case 8: { + value->replace(&v, sizeof(v), value->type); + break; + } + default: + ctx->log(SEVERITY_ERROR, "Wrong size of stack value for operation %s(%d)", map->op_name, value->size); + return false; + break; + } + + return true; + } + + return false; +} + +bool dw_op_not(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_neg operation pops the top stack entry, interprets it as a signed value and pushes its negation. + // If the negation cannot be represented, the result is undefined. + + dwarf_value* value = ctx->stack.get(); + if(value) { + uint64_t v = 0; + if(!value->get_uint(v)) { + ctx->log(SEVERITY_ERROR, "Wrong size of stack value for operation %s(%d)", map->op_name, value->size); + return false; + } + v = !v; + + value->replace(&v, value->size, value->type); + + return true; + } + + return false; +} + +bool dw_op_or(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_or operation pops the top two stack entries, performs a bitwise or operation on the two, and pushes the result. + + dwarf_value* value1 = ctx->stack.pop(); + dwarf_value* value2 = ctx->stack.pop(); + if(value1 && value2) { + if(value1->type != value2->type) { + ctx->log(SEVERITY_ERROR, "Different types of two stack values for operation: %s(%d, %d)", map->op_name, value1->type, value2->type); + return false; + } + uint64_t v1 = 0, v2 = 0; + if(!value1->get_uint(v1)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 1st stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + if(!value2->get_uint(v2)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 2nd stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + uint64_t res = v2 | v1; + ctx->stack.push(&res, value1->size, value1->type); + return true; + } + + return false; +} + +bool dw_op_plus(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_plus operation pops the top two stack entries, adds them together, and pushes the result + + dwarf_value* value1 = ctx->stack.pop(); + dwarf_value* value2 = ctx->stack.pop(); + if(value1 && value2) { + if(value1->type != value2->type) { + ctx->log(SEVERITY_ERROR, "Different types of two stack values for operation: %s(%d, %d)", map->op_name, value1->type, value2->type); + return false; + } + int64_t v1 = 0, v2 = 0; + if(!value1->get_int(v1)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 1st stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + if(!value2->get_int(v2)) { + ctx->log(SEVERITY_ERROR, "Wrong size of 2nd stack value for operation %s(%d)", map->op_name, value1->size); + return false; + } + + uint64_t res = v2 + v1; + ctx->stack.push(&res, value1->size, value1->type); + return true; + } + + return false; +} + +bool dw_op_plus_uconst(pst_context* ctx, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2) +{ + // The DW_OP_plus_uconst operation pops the top stack entry, adds it to the unsigned LEB128 constant operand interpreted as the same type as the + // operand popped from the top of the stack and pushes the result. + // This operation is supplied specifically to be able to encode more field offsets in two + // bytes than can be done with “DW_OP_lit DW_OP_plus.” + + dwarf_value* value = ctx->stack.get(); + if(value) { + if(value->type != DWARF_TYPE_SIGNED && value->type != DWARF_TYPE_UNSIGNED) { + ctx->log(SEVERITY_ERROR, "Invalid type for operation %s(%d)", map->op_name, value->type); + return false; + } + + uint64_t op = decode_uleb128((unsigned char*)&op1); + if(value->type == DWARF_TYPE_SIGNED) { + int64_t v = 0; + if(!value->get_int(v)) { + ctx->log(SEVERITY_ERROR, "Wrong size of stack value for operation %s(%d)", map->op_name, value->size); + return false; + } + v += op; + value->replace(&v, sizeof(v), value->type); + } else { + uint64_t v = 0; + if(!value->get_uint(v)) { + ctx->log(SEVERITY_ERROR, "Wrong size of stack value for operation %s(%d)", map->op_name, value->size); + return false; + } + v += op; + value->replace(&v, sizeof(v), value->type); + } + + return true; + } + + return false; +} + dwarf_op_map dw_op[] = { - {0x03, -1, 0, "DW_OP_addr", dw_op_addr}, - {0x23, 0x0, 0, "DW_OP_plus_uconst"}, + {DW_OP_addr, -1, 0, "DW_OP_addr", dw_op_addr}, + {DW_OP_deref, -1, 0, "DW_OP_deref", dw_op_deref}, + // Constant operations + {DW_OP_const1u, -1, 0, "DW_OP_const1u", dw_op_const_x_u}, + {DW_OP_const1s, -1, 0, "DW_OP_const1s", dw_op_const_x_s}, + {DW_OP_const2u, -1, 0, "DW_OP_const2u", dw_op_const_x_u}, + {DW_OP_const2s, -1, 0, "DW_OP_const2s", dw_op_const_x_s}, + {DW_OP_const4u, -1, 0, "DW_OP_const4u", dw_op_const_x_u}, + {DW_OP_const4s, -1, 0, "DW_OP_const4s", dw_op_const_x_s}, + {DW_OP_const8u, -1, 0, "DW_OP_const8u", dw_op_const_x_u}, + {DW_OP_const8s, -1, 0, "DW_OP_const8s", dw_op_const_x_s}, + {DW_OP_constu, -1, 0, "DW_OP_constu", dw_op_constu}, + {DW_OP_consts, -1, 0, "DW_OP_consts", dw_op_consts}, + // DWARF expression stack operations + {DW_OP_dup, -1, 0, "DW_OP_dup", dw_op_dup}, + {DW_OP_drop, -1, 0, "DW_OP_drop", dw_op_drop}, + {DW_OP_over, -1, 0, "DW_OP_over", dw_op_over}, + {DW_OP_pick, -1, 0, "DW_OP_pick", dw_op_pick}, + {DW_OP_swap, -1, 0, "DW_OP_swap", dw_op_swap}, + {DW_OP_rot, -1, 0, "DW_OP_rot", dw_op_rot}, + {DW_OP_xderef, -1, 0, "DW_OP_xderef", dw_op_notimpl}, + // Arithmetic and Logical Operations + {DW_OP_abs, -1, 0, "DW_OP_abs", dw_op_abs}, + {DW_OP_and, -1, 0, "DW_OP_and", dw_op_and}, + {DW_OP_div, -1, 0, "DW_OP_div", dw_op_div}, + {DW_OP_minus, -1, 0, "DW_OP_minus", dw_op_minus}, + {DW_OP_mod, -1, 0, "DW_OP_mod", dw_op_mod}, + {DW_OP_mul, -1, 0, "DW_OP_mul", dw_op_mul}, + {DW_OP_neg, -1, 0, "DW_OP_neg", dw_op_neg}, + {DW_OP_not, -1, 0, "DW_OP_not", dw_op_not}, + {DW_OP_or, -1, 0, "DW_OP_or", dw_op_or}, + {DW_OP_plus, -1, 0, "DW_OP_plus", dw_op_plus}, + {DW_OP_plus_uconst, 0x0, 0, "DW_OP_plus_uconst", dw_op_plus_uconst}, // Register location descriptions. From DWARF 5, section 2.6.1.1.3: // Register location descriptions describe an object (or a piece of an object) that resides in a register. // A register location description must stand alone as the entire description of an object or a piece of an object. diff --git a/framework/sysutils.cpp b/framework/sysutils.cpp index becabcb..06b4c26 100644 --- a/framework/sysutils.cpp +++ b/framework/sysutils.cpp @@ -111,12 +111,12 @@ void print_framereg(int regno) } */ -bool __pst_handler::calc_expr_block(Dwarf_Op *exprs, int expr_len, dwarf_stack* stack, Dwarf_Attribute* attr) +bool __pst_handler::calc_expression(Dwarf_Op *exprs, int expr_len, dwarf_stack* stack, Dwarf_Attribute* attr) { for (int i = 0; i < expr_len; i++) { const dwarf_op_map* map = find_op_map(exprs[i].atom); if(!map) { - ctx.log(SEVERITY_ERROR, "Unknown operation type 0x%hhX", exprs[i].atom); + ctx.log(SEVERITY_ERROR, "Unknown operation type 0x%hhX(0x%lX, 0x%lX)", exprs[i].atom, exprs[i].number, exprs[i].number2); return false; } @@ -125,6 +125,7 @@ bool __pst_handler::calc_expr_block(Dwarf_Op *exprs, int expr_len, dwarf_stack* } if(!map->operation(&ctx, map, exprs[i].number, exprs[i].number2)) { + ctx.log(SEVERITY_ERROR, "Failed to calculate %s(0x%lX, 0x%lX) operation", map->op_name, exprs[i].number, exprs[i].number2); return false; } } diff --git a/framework/sysutils.h b/framework/sysutils.h index dc09560..e273034 100644 --- a/framework/sysutils.h +++ b/framework/sysutils.h @@ -98,7 +98,7 @@ typedef struct __pst_handler { void dwarf_print(); - bool calc_expr_block(Dwarf_Op *exprs, int exp_len, dwarf_stack* stack, Dwarf_Attribute* attr = 0); + bool calc_expression(Dwarf_Op *exprs, int exp_len, dwarf_stack* stack, Dwarf_Attribute* attr = 0); bool unwind(); bool get_frame(); bool get_dwarf_function(pst_function& fun);