4
* Created on: Jan 11, 2020
14
#include "dwarf_operations.h"
16
// not implemented operations
17
static bool dw_op_notimpl(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
19
pst_log(SEVERITY_WARNING, "Not implemented DWARF operation %s(0x%X)", map->op_name, map->op_num);
23
// The DW_OP_addr operation has a single operand that encodes a machine
24
// address and whose size is the size of an address on the target machine.
25
static bool dw_op_addr(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
27
pst_dwarf_stack_push(stack, &op1, sizeof(op1), DWARF_TYPE_GENERIC);
31
// The DW_OP_deref_size operation behaves like the DW_OP_deref operation. In the DW_OP_deref_size operation, however, the size
32
// in bytes of the data retrieved from the dereferenced address is specified by the single operand. This operand is a 1-byte unsigned integral constant
33
// whose value may not be larger than the size of the generic type. The data
34
// retrieved is zero extended to the size of an address on the target machine
35
// before being pushed onto the expression stack.
37
static bool dw_op_deref_size(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
39
pst_dwarf_value* value = pst_dwarf_stack_pop(stack);
41
uint64_t addr = value->value.uint64;
45
res = *((uint8_t*)addr);
48
res = *((uint16_t*)addr);
51
res = *((uint32_t*)addr);
54
res = *((uint64_t*)addr);
60
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_GENERIC);
67
// The DW_ OP_deref operation pops the top stack entry and treats it as an address.
68
// The popped value must have an integral type. The value retrieved from that address is pushed, and has the generic type.
69
// The size of the data retrieved from the dereferenced address is the size of an address on the target machine.
70
static bool dw_op_deref(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
72
return dw_op_deref_size(stack, map, 8, op2);
75
// DW_OP_const1u, DW_OP_const2u, DW_OP_const4u, DW_OP_const8u. The single operand of a DW_OP_const<n>u operation provides a 1, 2, 4, or 8-byte unsigned integer constant, respectively.
76
// These operations push a value with the generic type
77
static bool dw_op_const_x_u(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
80
pst_dwarf_value_type type = DWARF_TYPE_UNSIGNED;
81
switch (map->op_num) {
84
type = DWARF_TYPE_CHAR;
88
type = DWARF_TYPE_SHORT;
92
type = DWARF_TYPE_INT;
96
type = DWARF_TYPE_LONG;
102
pst_dwarf_stack_push(stack, &op1, size, type | DWARF_TYPE_CONST | DWARF_TYPE_GENERIC);
107
// DW_OP_const1s, DW_OP_const2s, DW_OP_const4s, DW_OP_const8s. The single operand of a DW_OP_const<n>s operation provides a 1, 2, 4, or 8-byte signed integer constant, respectively.
108
// These operations push a value with the generic type
109
static bool dw_op_const_x_s(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
111
uint8_t size; int64_t v;
112
pst_dwarf_value_type type = DWARF_TYPE_SIGNED;
113
switch (map->op_num) {
116
size = sizeof(int8_t);
117
type = DWARF_TYPE_CHAR;
121
size = sizeof(int16_t);
122
type = DWARF_TYPE_SHORT;
126
size = sizeof(int32_t);
127
type = DWARF_TYPE_INT;
131
size = sizeof(int64_t);
132
type = DWARF_TYPE_LONG;
138
pst_dwarf_stack_push(stack, &v, size, type | DWARF_TYPE_CONST | DWARF_TYPE_GENERIC);
143
// The single operand of the DW_OP_constu operation provides an unsigned LEB128 integer constant.
144
static bool dw_op_constu(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
146
uint64_t value = decode_uleb128((unsigned char*)&op1);
147
pst_dwarf_stack_push(stack, &value, sizeof(value), DWARF_TYPE_LONG | DWARF_TYPE_UNSIGNED | DWARF_TYPE_CONST | DWARF_TYPE_GENERIC);
151
static bool dw_op_consts(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
153
// The single operand of the DW_OP_consts operation provides a signed LEB128 integer constant.
154
int64_t value = decode_sleb128((unsigned char*)&op1);
155
pst_dwarf_stack_push(stack, &value, sizeof(value), DWARF_TYPE_LONG | DWARF_TYPE_SIGNED | DWARF_TYPE_CONST | DWARF_TYPE_GENERIC);
159
// The DW_OP_dup operation duplicates the value (including its type identifier) at the top of the stack.
160
static bool dw_op_dup(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
162
pst_dwarf_value* value = pst_dwarf_stack_get(stack, 0);
163
pst_dwarf_stack_push(stack, &value->value, sizeof(value->value), value->type);
168
// The DW_OP_drop operation pops the value (including its type identifier) at the top of the stack.
169
static bool dw_op_drop(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
171
pst_dwarf_value* value = pst_dwarf_stack_pop(stack);
172
pst_dwarf_value_fini(value);
177
// The DW_OP_over operation duplicates the entry currently second in the stack at the top of the stack.
178
// This is equivalent to a DW_OP_pick operation, with index 1.
179
static bool dw_op_over(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
181
pst_dwarf_value* value = pst_dwarf_stack_get(stack, 1);
182
pst_dwarf_stack_push(stack, &value->value, sizeof(value->value), value->type);
187
// The single operand of the DW_OP_pick operation provides a 1-byte index.
188
// A copy of the stack entry (including its type identifier) with the specified index (0 through 255, inclusive) is pushed onto the stack.
189
static bool dw_op_pick(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
191
pst_dwarf_value* value = pst_dwarf_stack_get(stack, op1);
193
pst_dwarf_stack_push(stack, &value->value, sizeof(value->value), value->type);
200
// 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
201
// entry, and the second entry (including its type identifier) becomes the top of the stack.
202
static bool dw_op_swap(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
204
pst_dwarf_value* value1 = pst_dwarf_stack_pop(stack);
205
pst_dwarf_value* value2 = pst_dwarf_stack_pop(stack);
206
if(value1 && value2) {
207
pst_dwarf_stack_push_value(stack, value1);
208
pst_dwarf_stack_push_value(stack, value2);
213
pst_dwarf_value_fini(value1);
216
pst_dwarf_value_fini(value2);
222
// The DW_OP_rot operation rotates the first three stack entries.
223
// The entry at the top of the stack (including its type identifier) becomes the third stack entry,
224
// the second entry (including its type identifier) becomes the top of the stack,
225
// and the third entry (including its type identifier) becomes the second entry
226
static bool dw_op_rot(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
228
pst_dwarf_value* value1 = pst_dwarf_stack_pop(stack);
229
pst_dwarf_value* value2 = pst_dwarf_stack_pop(stack);
230
pst_dwarf_value* value3 = pst_dwarf_stack_pop(stack);
231
if(value1 && value2 && value3) {
232
pst_dwarf_stack_push_value(stack, value1);
233
pst_dwarf_stack_push_value(stack, value3);
234
pst_dwarf_stack_push_value(stack, value2);
239
pst_dwarf_value_fini(value1);
242
pst_dwarf_value_fini(value2);
245
pst_dwarf_value_fini(value3);
251
// The DW_OP_abs operation pops the top stack entry, interprets it as a signed value and pushes its absolute value.
252
// If the absolute value cannot be represented, the result is undefined.
253
static bool dw_op_abs(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
255
pst_dwarf_value* value = pst_dwarf_stack_get(stack, 0);
257
uint64_t res = llabs(value->value.int64);
258
pst_dwarf_value_set(value, &res, sizeof(res), DWARF_TYPE_UNSIGNED | DWARF_TYPE_GENERIC | DWARF_TYPE_LONG);
264
// The DW_OP_and operation pops the top two stack values, performs a bitwise and operation on the two, and pushes the result.
265
static bool dw_op_and(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
267
pst_dwarf_value* value1 = pst_dwarf_stack_get(stack, 0);
268
pst_dwarf_value* value2 = pst_dwarf_stack_get(stack, 1);
269
if(value1 && value2) {
270
if(!(value1->type & value2->type)) {
274
uint64_t res = value1->value.uint64 & value2->value.uint64;
275
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
276
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_GENERIC);
278
pst_dwarf_value_fini(value1);
279
pst_dwarf_value_fini(value2);
286
// 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.
287
static bool dw_op_div(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
289
pst_dwarf_value* value1 = pst_dwarf_stack_get(stack, 0);
290
pst_dwarf_value* value2 = pst_dwarf_stack_get(stack, 1);
291
if(value1 && value2) {
292
if(!(value1->type & value2->type)) {
296
if(value2->type & DWARF_TYPE_SIGNED) {
297
if(value1->type & DWARF_TYPE_SIGNED) {
298
if(value1->value.int64 == 0) {
301
uint64_t res = value2->value.int64 / value1->value.int64;
302
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
303
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_UNSIGNED | DWARF_TYPE_GENERIC);
306
if(value1->value.uint64 == 0) {
309
int64_t res = value2->value.int64 / value1->value.uint64;
310
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
311
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_SIGNED | DWARF_TYPE_GENERIC);
315
if(value1->type & DWARF_TYPE_SIGNED) {
316
if(value1->value.int64 == 0) {
319
int64_t res = value2->value.uint64 / value1->value.int64;
320
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
321
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_SIGNED | DWARF_TYPE_GENERIC);
324
if(value1->value.uint64 == 0) {
327
uint64_t res = value2->value.uint64 / value1->value.uint64;
328
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
329
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_UNSIGNED | DWARF_TYPE_GENERIC);
338
// 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.
339
static bool dw_op_minus(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
341
pst_dwarf_value* value1 = pst_dwarf_stack_get(stack, 0);
342
pst_dwarf_value* value2 = pst_dwarf_stack_get(stack, 1);
343
if(value1 && value2) {
344
if(!(value1->type & value2->type)) {
348
int res_type = DWARF_TYPE_GENERIC;
349
if(value2->type & DWARF_TYPE_MEMORY_LOC) {
350
res_type |= DWARF_TYPE_MEMORY_LOC;
352
// use arithmetic by modulo 1 plus
353
uint64_t res = value2->value.uint64 - value1->value.uint64;
354
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
355
pst_dwarf_stack_push(stack, &res, sizeof(res), res_type);
363
// 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.
364
static bool dw_op_mod(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
366
pst_dwarf_value* value1 = pst_dwarf_stack_get(stack, 0);
367
pst_dwarf_value* value2 = pst_dwarf_stack_get(stack, 1);
368
if(value1 && value2) {
369
if(!(value1->type & value2->type)) {
373
if(value1->value.uint64 == 0) {
377
uint64_t res = value2->value.uint64 % value1->value.uint64;
378
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
379
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_UNSIGNED | DWARF_TYPE_GENERIC);
387
// The DW_OP_mul operation pops the top two stack entries, multiplies them together, and pushes the result.
388
static bool dw_op_mul(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
390
pst_dwarf_value* value1 = pst_dwarf_stack_get(stack, 0);
391
pst_dwarf_value* value2 = pst_dwarf_stack_get(stack, 1);
392
if(value1 && value2) {
393
if(!(value1->type & value2->type)) {
394
pst_log(SEVERITY_ERROR, "Different types of two stack values for operation: %s(%0x%X, %0x%X)", map->op_name, value1->type, value2->type);
398
if(value2->type & DWARF_TYPE_SIGNED) {
399
if(value1->type & DWARF_TYPE_SIGNED) {
400
uint64_t res = value2->value.int64 * value1->value.int64;
401
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
402
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_UNSIGNED | DWARF_TYPE_GENERIC);
406
int64_t res = value2->value.int64 * value1->value.uint64;
407
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
408
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_SIGNED | DWARF_TYPE_GENERIC);
413
if(value1->type & DWARF_TYPE_SIGNED) {
414
int64_t res = value2->value.uint64 * value1->value.int64;
415
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
416
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_SIGNED | DWARF_TYPE_GENERIC);
420
uint64_t res = value2->value.uint64 * value1->value.uint64;
421
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
422
pst_dwarf_stack_push(stack, &res, sizeof(res), DWARF_TYPE_UNSIGNED | DWARF_TYPE_GENERIC);
432
// The DW_OP_neg operation pops the top stack entry, interprets it as a signed value and pushes its negation.
433
// If the negation cannot be represented, the result is undefined.
434
static bool dw_op_neg(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
436
pst_dwarf_value* value = pst_dwarf_stack_get(stack, 0);
438
if(value->type & DWARF_TYPE_CHAR) {
439
value->value.int8 *= -1;
440
} else if(value->type & DWARF_TYPE_SHORT) {
441
value->value.int16 *= -1;
442
} else if(value->type & DWARF_TYPE_INT) {
443
value->value.int32 *= -1;
445
value->value.int64 *= -1;
453
// The DW_OP_not operation pops the top stack entry, and pushes its bitwise complement.
454
static bool dw_op_not(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
456
pst_dwarf_value* value = pst_dwarf_stack_get(stack, 0);
458
value->value.uint64 = ~value->value.uint64;
466
// The DW_OP_or operation pops the top two stack entries, performs a bitwise or operation on the two, and pushes the result.
467
static bool dw_op_or(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
469
pst_dwarf_value* value1 = pst_dwarf_stack_get(stack, 0);
470
pst_dwarf_value* value2 = pst_dwarf_stack_get(stack, 1);
471
if(value1 && value2) {
472
if(!(value1->type & value2->type)) {
476
uint64_t res = value2->value.uint64 | value1->value.uint64;
477
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
478
pst_dwarf_stack_push(stack, &res, sizeof(res), value1->type);
480
pst_dwarf_value_fini(value1);
481
pst_dwarf_value_fini(value2);
489
// The DW_OP_plus operation pops the top two stack entries, adds them together, and pushes the result
490
static bool dw_op_plus(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
492
pst_dwarf_value* value1 = pst_dwarf_stack_get(stack, 0);
493
pst_dwarf_value* value2 = pst_dwarf_stack_get(stack, 1);
494
if(value1 && value2) {
495
if(!(value1->type & value2->type)) {
499
if((value1->type & DWARF_TYPE_SIGNED) && (value2->type & DWARF_TYPE_SIGNED)) {
500
int64_t res = value2->value.int64 + value1->value.int64;
501
pst_dwarf_stack_push(stack, &res, sizeof(res), value1->type);
503
// if in arithmetic expression even one operand is unsigned then result is unsigned as well
504
int type = (value1->type & (~DWARF_TYPE_SIGNED)) | DWARF_TYPE_UNSIGNED;
505
uint64_t res = value2->value.uint64 + value1->value.uint64;
506
pst_dwarf_stack_push(stack, &res, sizeof(res), type);
509
pst_dwarf_stack_pop(stack); pst_dwarf_stack_pop(stack);
510
pst_dwarf_value_fini(value1);
511
pst_dwarf_value_fini(value2);
519
// 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
520
// operand popped from the top of the stack and pushes the result.
521
// This operation is supplied specifically to be able to encode more field offsets in two
522
// bytes than can be done with “DW_OP_lit<n> DW_OP_plus.”
523
static bool dw_op_plus_uconst(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
525
pst_dwarf_value* value = pst_dwarf_stack_get(stack, 0);
527
uint64_t op = decode_uleb128((unsigned char*)&op1);
528
value->value.uint64 += op;
536
// Register location descriptions. Describe an object (or a piece of an object) that resides in a register.
537
// A register location description must stand alone as the entire description of an object or a piece of an object.
538
// The DW_OP_regx operation has a single unsigned LEB128 literal operand that encodes the name of a register
539
static bool dw_op_reg_x(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
541
if(map->op_num != DW_OP_regx && (map->op_num < DW_OP_reg0 || map->op_num > DW_OP_reg31)) {
546
if(map->op_num == DW_OP_regx) {
547
regno = decode_uleb128((unsigned char*)&op1);
549
regno = map->op_num - DW_OP_reg0;
552
pst_dwarf_stack_push(stack, ®no, sizeof(regno), DWARF_TYPE_REGISTER_LOC);
557
// DWARF5, section 2.5.1.2 Register values are used to describe an object (or a piece of an object) that is located in memory at an address that is contained in a register (possibly offset by some constant)
558
// The DW_OP_bregx operation provides the sum of two values specified by its two operands.
559
// The first operand is a register number which is specified by an unsigned LEB128 number. The second operand is a signed LEB128 offset.
560
static bool dw_op_breg_x(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
562
if(map->op_num != DW_OP_bregx && (map->op_num < DW_OP_breg0 || map->op_num > DW_OP_breg31)) {
566
int regno = -1; int64_t off = 0;
567
if(map->op_num == DW_OP_bregx) {
568
regno = decode_uleb128((unsigned char*)&op1);
569
off = decode_sleb128((unsigned char*)&op2);
571
regno = find_regnum(map->op_num);
572
off = decode_sleb128((unsigned char*)&op1);
576
int ret = unw_get_reg(stack->ctx->curr_frame, regno, &val);
582
pst_dwarf_stack_push(stack, &val, sizeof(val), DWARF_TYPE_GENERIC);
587
// The DW_OP_lit<n> operations encode the unsigned literal values from 0 through 31, inclusive.
588
// Operations other than DW_OP_const_type push a value with the generic type.
589
static bool dw_op_lit_x(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
591
if(map->op_num < DW_OP_lit0 || map->op_num > DW_OP_lit31) {
595
uint64_t val = map->op_num - DW_OP_lit0;
596
pst_dwarf_stack_push(stack, &val, sizeof(val), DWARF_TYPE_GENERIC);
601
// The DW_OP_stack_value operation specifies that the object does not exist in memory but its value is nonetheless known and is at the top of the DWARF
602
// expression stack. In this form of location description, the DWARF expression represents the actual value of the object, rather than its location.
603
// The DW_OP_stack_value operation terminates the expression.
604
static bool dw_op_stack_value(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
607
pst_dwarf_value* v = pst_dwarf_stack_get(stack, 0);
609
v->type = DWARF_TYPE_GENERIC;
616
// The DW_OP_call_frame_cfa operation pushes the value of the CFA, obtained from the Call Frame Information (see Section 6.4 on page 171).
617
static bool dw_op_call_frame_cfa(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
619
// since we are already know SP value, just push it to DWARF stack
621
// int ret = unw_get_reg(stack->ctx->curr_frame, UNW_REG_SP, &sp);
623
// pst_log(SEVERITY_ERROR, "%s: failed to get register 0x%X value. Error: %d", __PRETTY_FUNCTION__, UNW_REG_SP, ret);
627
pst_dwarf_stack_push(stack, &stack->ctx->cfa, sizeof(stack->ctx->cfa), /*DWARF_TYPE_MEMORY_LOC | */DWARF_TYPE_GENERIC);
632
// The DW_OP_fbreg operation provides a signed LEB128 offset from the address specified by the location description in the DW_AT_frame_base
633
// attribute of the current function. This is typically a stack pointer register plus or minus some offset
634
static bool dw_op_fbreg(pst_dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dwarf_Word op2)
636
// since in signal handler we are know SP value, just use it as DW_AT_frame_base
638
// int ret = unw_get_reg(stack->ctx->curr_frame, UNW_REG_SP, &sp);
640
// pst_log(SEVERITY_ERROR, "Failed to get register 0x%X value. Error: %d", __PRETTY_FUNCTION__, UNW_REG_SP, ret);
644
sp = stack->ctx->cfa;
645
int64_t off = decode_sleb128((unsigned char*)&op1);
648
pst_dwarf_stack_push(stack, &sp, sizeof(sp), DWARF_TYPE_MEMORY_LOC | DWARF_TYPE_GENERIC);
653
// DWARF Operations to code & name mapping
654
dwarf_op_map op_map[] = {
655
{DW_OP_addr, "DW_OP_addr", dw_op_addr},
656
{DW_OP_deref, "DW_OP_deref", dw_op_deref},
657
// Constant operations
658
{DW_OP_const1u, "DW_OP_const1u", dw_op_const_x_u},
659
{DW_OP_const1s, "DW_OP_const1s", dw_op_const_x_s},
660
{DW_OP_const2u, "DW_OP_const2u", dw_op_const_x_u},
661
{DW_OP_const2s, "DW_OP_const2s", dw_op_const_x_s},
662
{DW_OP_const4u, "DW_OP_const4u", dw_op_const_x_u},
663
{DW_OP_const4s, "DW_OP_const4s", dw_op_const_x_s},
664
{DW_OP_const8u, "DW_OP_const8u", dw_op_const_x_u},
665
{DW_OP_const8s, "DW_OP_const8s", dw_op_const_x_s},
666
{DW_OP_constu, "DW_OP_constu", dw_op_constu},
667
{DW_OP_consts, "DW_OP_consts", dw_op_consts},
668
// DWARF expression stack operations
669
{DW_OP_dup, "DW_OP_dup", dw_op_dup},
670
{DW_OP_drop, "DW_OP_drop", dw_op_drop},
671
{DW_OP_over, "DW_OP_over", dw_op_over},
672
{DW_OP_pick, "DW_OP_pick", dw_op_pick},
673
{DW_OP_swap, "DW_OP_swap", dw_op_swap},
674
{DW_OP_rot, "DW_OP_rot", dw_op_rot},
675
{DW_OP_xderef, "DW_OP_xderef", dw_op_notimpl},
676
// Arithmetic and Logical Operations
677
{DW_OP_abs, "DW_OP_abs", dw_op_abs},
678
{DW_OP_and, "DW_OP_and", dw_op_and},
679
{DW_OP_div, "DW_OP_div", dw_op_div},
680
{DW_OP_minus, "DW_OP_minus", dw_op_minus},
681
{DW_OP_mod, "DW_OP_mod", dw_op_mod},
682
{DW_OP_mul, "DW_OP_mul", dw_op_mul},
683
{DW_OP_neg, "DW_OP_neg", dw_op_neg},
684
{DW_OP_not, "DW_OP_not", dw_op_not},
685
{DW_OP_or, "DW_OP_or", dw_op_or},
686
{DW_OP_plus, "DW_OP_plus", dw_op_plus},
687
{DW_OP_plus_uconst, "DW_OP_plus_uconst",dw_op_plus_uconst},
688
// not implemented for now
689
{DW_OP_shl, "DW_OP_shl", dw_op_notimpl},
690
{DW_OP_shr, "DW_OP_shr", dw_op_notimpl},
691
{DW_OP_shra, "DW_OP_shra", dw_op_notimpl},
692
{DW_OP_xor, "DW_OP_xor", dw_op_notimpl},
693
{DW_OP_bra, "DW_OP_bra", dw_op_notimpl},
694
{DW_OP_eq, "DW_OP_eq", dw_op_notimpl},
695
{DW_OP_ge, "DW_OP_ge", dw_op_notimpl},
696
{DW_OP_gt, "DW_OP_gt", dw_op_notimpl},
697
{DW_OP_le, "DW_OP_le", dw_op_notimpl},
698
{DW_OP_lt, "DW_OP_lt", dw_op_notimpl},
699
{DW_OP_ne, "DW_OP_ne", dw_op_notimpl},
700
{DW_OP_skip, "DW_OP_skip", dw_op_notimpl},
701
// DWARF5 2.5.1.1 Literal Encodings
702
{DW_OP_lit0, "DW_OP_lit0", dw_op_lit_x},
703
{DW_OP_lit1, "DW_OP_lit1", dw_op_lit_x},
704
{DW_OP_lit2, "DW_OP_lit2", dw_op_lit_x},
705
{DW_OP_lit3, "DW_OP_lit3", dw_op_lit_x},
706
{DW_OP_lit4, "DW_OP_lit4", dw_op_lit_x},
707
{DW_OP_lit5, "DW_OP_lit5", dw_op_lit_x},
708
{DW_OP_lit6, "DW_OP_lit6", dw_op_lit_x},
709
{DW_OP_lit7, "DW_OP_lit7", dw_op_lit_x},
710
{DW_OP_lit8, "DW_OP_lit8", dw_op_lit_x},
711
{DW_OP_lit9, "DW_OP_lit9", dw_op_lit_x},
712
{DW_OP_lit10, "DW_OP_lit10", dw_op_lit_x},
713
{DW_OP_lit11, "DW_OP_lit11", dw_op_lit_x},
714
{DW_OP_lit12, "DW_OP_lit12", dw_op_lit_x},
715
{DW_OP_lit13, "DW_OP_lit13", dw_op_lit_x},
716
{DW_OP_lit14, "DW_OP_lit14", dw_op_lit_x},
717
{DW_OP_lit15, "DW_OP_lit15", dw_op_lit_x},
718
{DW_OP_lit16, "DW_OP_lit16", dw_op_lit_x},
719
{DW_OP_lit17, "DW_OP_lit17", dw_op_lit_x},
720
{DW_OP_lit18, "DW_OP_lit18", dw_op_lit_x},
721
{DW_OP_lit19, "DW_OP_lit19", dw_op_lit_x},
722
{DW_OP_lit20, "DW_OP_lit20", dw_op_lit_x},
723
{DW_OP_lit21, "DW_OP_lit21", dw_op_lit_x},
724
{DW_OP_lit22, "DW_OP_lit22", dw_op_lit_x},
725
{DW_OP_lit23, "DW_OP_lit23", dw_op_lit_x},
726
{DW_OP_lit24, "DW_OP_lit24", dw_op_lit_x},
727
{DW_OP_lit25, "DW_OP_lit25", dw_op_lit_x},
728
{DW_OP_lit26, "DW_OP_lit26", dw_op_lit_x},
729
{DW_OP_lit27, "DW_OP_lit27", dw_op_lit_x},
730
{DW_OP_lit28, "DW_OP_lit28", dw_op_lit_x},
731
{DW_OP_lit29, "DW_OP_lit29", dw_op_lit_x},
732
{DW_OP_lit30, "DW_OP_lit30", dw_op_lit_x},
733
{DW_OP_lit31, "DW_OP_lit31", dw_op_lit_x},
734
// Register location descriptions. I.e. register containing the value
736
{DW_OP_reg0, "DW_OP_reg0", dw_op_reg_x},
737
{DW_OP_reg1, "DW_OP_reg1", dw_op_reg_x},
738
{DW_OP_reg2, "DW_OP_reg2", dw_op_reg_x},
739
{DW_OP_reg3, "DW_OP_reg3", dw_op_reg_x},
740
{DW_OP_reg4, "DW_OP_reg4", dw_op_reg_x},
741
{DW_OP_reg5, "DW_OP_reg5", dw_op_reg_x},
742
{DW_OP_reg6, "DW_OP_reg6", dw_op_reg_x},
743
{DW_OP_reg7, "DW_OP_reg7", dw_op_reg_x},
744
// Extended GP Registers
745
{DW_OP_reg8, "DW_OP_reg8", dw_op_reg_x},
746
{DW_OP_reg9, "DW_OP_reg9", dw_op_reg_x},
747
{DW_OP_reg10, "DW_OP_reg10", dw_op_reg_x},
748
{DW_OP_reg11, "DW_OP_reg11", dw_op_reg_x},
749
{DW_OP_reg12, "DW_OP_reg12", dw_op_reg_x},
750
{DW_OP_reg13, "DW_OP_reg13", dw_op_reg_x},
751
{DW_OP_reg14, "DW_OP_reg14", dw_op_reg_x},
752
{DW_OP_reg15, "DW_OP_reg15", dw_op_reg_x},
753
{DW_OP_reg16, "DW_OP_reg16", dw_op_reg_x}, // Return Address (RA) mapped to RIP
754
// SSE Vector Registers
755
{DW_OP_reg17, "DW_OP_reg17", dw_op_reg_x},
756
{DW_OP_reg18, "DW_OP_reg18", dw_op_reg_x},
757
{DW_OP_reg19, "DW_OP_reg19", dw_op_reg_x},
758
{DW_OP_reg20, "DW_OP_reg20", dw_op_reg_x},
759
{DW_OP_reg21, "DW_OP_reg21", dw_op_reg_x},
760
{DW_OP_reg22, "DW_OP_reg22", dw_op_reg_x},
761
{DW_OP_reg23, "DW_OP_reg23", dw_op_reg_x},
762
{DW_OP_reg24, "DW_OP_reg24", dw_op_reg_x},
763
{DW_OP_reg25, "DW_OP_reg25", dw_op_reg_x},
764
{DW_OP_reg26, "DW_OP_reg26", dw_op_reg_x},
765
{DW_OP_reg27, "DW_OP_reg27", dw_op_reg_x},
766
{DW_OP_reg28, "DW_OP_reg28", dw_op_reg_x},
767
{DW_OP_reg29, "DW_OP_reg29", dw_op_reg_x},
768
{DW_OP_reg30, "DW_OP_reg30", dw_op_reg_x},
769
{DW_OP_reg31, "DW_OP_reg31", dw_op_reg_x},
770
// Register values. I.e. appropriate register value + offset of operation is pushed onto the stack
772
{DW_OP_breg0, "DW_OP_breg0", dw_op_breg_x},
773
{DW_OP_breg1, "DW_OP_breg1", dw_op_breg_x},
774
{DW_OP_breg2, "DW_OP_breg2", dw_op_breg_x},
775
{DW_OP_breg3, "DW_OP_breg3", dw_op_breg_x},
776
{DW_OP_breg4, "DW_OP_breg4", dw_op_breg_x},
777
{DW_OP_breg5, "DW_OP_breg5", dw_op_breg_x},
778
{DW_OP_breg6, "DW_OP_breg6", dw_op_breg_x},
779
{DW_OP_breg7, "DW_OP_breg7", dw_op_breg_x},
780
// Extended GP Registers
781
{DW_OP_breg8, "DW_OP_breg8", dw_op_breg_x},
782
{DW_OP_breg9, "DW_OP_breg9", dw_op_breg_x},
783
{DW_OP_breg10, "DW_OP_breg10", dw_op_breg_x},
784
{DW_OP_breg11, "DW_OP_breg11", dw_op_breg_x},
785
{DW_OP_breg12, "DW_OP_breg12", dw_op_breg_x},
786
{DW_OP_breg13, "DW_OP_breg13", dw_op_breg_x},
787
{DW_OP_breg14, "DW_OP_breg14", dw_op_breg_x},
788
{DW_OP_breg15, "DW_OP_breg15", dw_op_breg_x},
789
{DW_OP_breg16, "DW_OP_breg16", dw_op_breg_x}, // Return Address (RA) mapped to RIP
790
// SSE Vector Registers
791
{DW_OP_breg17, "DW_OP_breg17", dw_op_breg_x},
792
{DW_OP_breg18, "DW_OP_breg18", dw_op_breg_x},
793
{DW_OP_breg19, "DW_OP_breg19", dw_op_breg_x},
794
{DW_OP_breg20, "DW_OP_breg20", dw_op_breg_x},
795
{DW_OP_breg21, "DW_OP_breg21", dw_op_breg_x},
796
{DW_OP_breg22, "DW_OP_breg22", dw_op_breg_x},
797
{DW_OP_breg23, "DW_OP_breg23", dw_op_breg_x},
798
{DW_OP_breg24, "DW_OP_breg24", dw_op_breg_x},
799
{DW_OP_breg25, "DW_OP_breg25", dw_op_breg_x},
800
{DW_OP_breg26, "DW_OP_breg26", dw_op_breg_x},
801
{DW_OP_breg27, "DW_OP_breg27", dw_op_breg_x},
802
{DW_OP_breg28, "DW_OP_breg28", dw_op_breg_x},
803
{DW_OP_breg29, "DW_OP_breg29", dw_op_breg_x},
804
{DW_OP_breg30, "DW_OP_breg30", dw_op_breg_x},
805
{DW_OP_breg31, "DW_OP_breg31", dw_op_breg_x},
806
// special register-related commands
807
{DW_OP_regx, "DW_OP_regx", dw_op_reg_x}, // 1st operand register name
808
{DW_OP_fbreg, "DW_OP_fbreg", dw_op_fbreg}, // base is Frame base register there
809
{DW_OP_bregx, "DW_OP_bregx", dw_op_breg_x}, // base is value of 1st operand's register
812
{DW_OP_piece, "DW_OP_piece", dw_op_notimpl},
813
{DW_OP_deref_size, "DW_OP_deref_size", dw_op_deref_size},
814
{DW_OP_xderef_size, "DW_OP_xderef_size", dw_op_notimpl},
815
{DW_OP_nop, "DW_OP_nop", dw_op_notimpl},
816
{DW_OP_push_object_address, "DW_OP_push_object_address",dw_op_notimpl},
817
{DW_OP_call2, "DW_OP_call2", dw_op_notimpl},
818
{DW_OP_call4, "DW_OP_call4", dw_op_notimpl},
819
{DW_OP_call_ref, "DW_OP_call_ref", dw_op_notimpl},
820
{DW_OP_form_tls_address, "DW_OP_form_tls_address", dw_op_notimpl},
821
{DW_OP_call_frame_cfa, "DW_OP_call_frame_cfa", dw_op_call_frame_cfa},
822
{DW_OP_bit_piece, "DW_OP_bit_piece", dw_op_notimpl},
823
{DW_OP_implicit_value, "DW_OP_implicit_value", dw_op_notimpl},
824
{DW_OP_stack_value, "DW_OP_stack_value", dw_op_stack_value},
827
// in fact, implementation is at upper layer since this operation contains sub-expression
828
{DW_OP_GNU_entry_value, "DW_OP_GNU_entry_value", dw_op_notimpl}, // seems that it's equal to DW_OP_entry_value from DWARF 5
831
const dwarf_op_map* find_op_map(int op)
833
for(uint32_t i = 0; i < sizeof(op_map) / sizeof(dwarf_op_map); ++i) {
834
if(op_map[i].op_num == op) {