4
* Created on: Jan 28, 2020
13
#include "dwarf/dwarf_operations.h"
14
#include "arch/registers.h"
17
extern dwarf_reg_map reg_map[];
20
pst_logger pstlogger; // logger for library
21
pst_allocator allocator; // custom allocator for PST library
23
static void clean_print(pst_context* ctx)
29
static void print_stack(pst_context* ctx, int max, uint64_t next_cfa)
31
pst_log(SEVERITY_DEBUG, "CFA = %#lX, NEXT_CFA = %#lX, SP = %#lX", ctx->cfa, next_cfa, ctx->sp);
32
ctx->clean_print(ctx);
34
if(ctx->cfa > ctx->sp) {
35
ctx->print(ctx, "Args: ");
36
for(; i < max && (ctx->cfa - i) > ctx->sp; ++i) {
37
ctx->print(ctx, "#%d 0x%lX ", i, *(uint64_t*)(ctx->cfa - i));
40
if((ctx->cfa - i) > next_cfa) {
41
ctx->print(ctx, "Vars: ");
42
for(; i < max && (ctx->cfa - i) > next_cfa; ++i) {
43
ctx->print(ctx, "#%d 0x%lX ", i, *(uint64_t*)(ctx->cfa - i));
48
static void print_registers(pst_context* ctx, int from, int to)
50
ctx->clean_print(ctx);
51
for(int i = from; i < regnum && i <= to; ++i) {
53
if(!unw_get_reg(ctx->curr_frame, reg_map[i].regno, ®val)) {
54
ctx->print(ctx, "%s: %#lX ", reg_map[i].regname, regval);
56
ctx->print(ctx, "%s: <undef>", reg_map[i].regname);
61
static bool print(pst_context* ctx, const char* fmt, ...)
67
int size = sizeof(ctx->buff) - ctx->offset;
68
int ret = vsnprintf(ctx->buff + ctx->offset, size, fmt, args);
69
if(ret >= size || ret < 0) {
78
static bool print_expr_block (pst_context* ctx, Dwarf_Op *exprs, int exprlen, Dwarf_Attribute* attr)
80
ctx->clean_print(ctx);
81
for (int i = 0; i < exprlen; i++) {
82
const dwarf_op_map* map = find_op_map(exprs[i].atom);
84
if(map->op_num >= DW_OP_breg0 && map->op_num <= DW_OP_breg16) {
85
int32_t off = decode_sleb128((unsigned char*)&exprs[i].number);
86
int regno = map->op_num - DW_OP_breg0;
88
unw_get_reg(ctx->curr_frame, regno, &ptr);
90
ctx->print(ctx, "%s(*%s%s%d) reg_value: 0x%lX", map->op_name, unw_regname(regno), off >=0 ? "+" : "", off, ptr);
91
} else if(map->op_num >= DW_OP_reg0 && map->op_num <= DW_OP_reg16) {
93
int regno = map->op_num - DW_OP_reg0;
94
unw_get_reg(ctx->curr_frame, regno, &value);
95
ctx->print(ctx, "%s(*%s) value: 0x%lX", map->op_name, unw_regname(regno), value);
96
} else if(map->op_num == DW_OP_GNU_entry_value) {
98
pst_log(SEVERITY_ERROR, "No attribute of DW_OP_GNU_entry_value provided");
101
uint32_t value = decode_uleb128((unsigned char*)&exprs[i].number);
102
ctx->print(ctx, "%s(%u, ", map->op_name, value);
103
Dwarf_Attribute attr_mem;
104
if(!dwarf_getlocation_attr(attr, exprs, &attr_mem)) {
107
if (dwarf_getlocation(&attr_mem, &expr, &exprlen) == 0) {
108
ctx->print_expr(ctx, expr, exprlen, &attr_mem);
109
ctx->print(ctx, ") ");
111
pst_log(SEVERITY_ERROR, "Failed to get DW_OP_GNU_entry_value attr location");
115
pst_log(SEVERITY_ERROR, "Failed to get DW_OP_GNU_entry_value attr expression");
118
} else if(map->op_num == DW_OP_stack_value) {
119
ctx->print(ctx, "%s", map->op_name);
120
} else if(map->op_num == DW_OP_plus_uconst) {
121
uint32_t value = decode_uleb128((unsigned char*)&exprs[i].number);
122
ctx->print(ctx, "%s(+%u) ", map->op_name, value);
123
} else if(map->op_num == DW_OP_bregx) {
124
uint32_t regno = decode_uleb128((unsigned char*)&exprs[i].number);
125
int32_t off = decode_sleb128((unsigned char*)&exprs[i].number2);
127
unw_get_reg(ctx->curr_frame, regno, &ptr);
129
ctx->print(ctx, "%s(%s%s%d) reg_value = 0x%lX", map->op_name, unw_regname(regno), off >= 0 ? "+" : "", off, ptr);
130
} else if(map->op_num == DW_OP_regx) {
131
int32_t reg = decode_sleb128((unsigned char*)&exprs[i].number);
133
unw_word_t value = 0;
134
unw_get_reg(ctx->curr_frame, reg, &value);
136
ctx->print(ctx, "%s(%s) value = 0x%lX", map->op_name, unw_regname(reg), value);
137
} else if(map->op_num == DW_OP_addr) {
138
ctx->print(ctx, "%s value = %p", map->op_name, (void*)exprs[i].number);
139
} else if(map->op_num == DW_OP_fbreg) {
140
int32_t off = decode_sleb128((unsigned char*)&exprs[i].number);
141
ctx->print(ctx, "%s(SP%s%d) ", map->op_name, off >=0 ? "+" : "", off);
143
ctx->print(ctx, "%s(0x%lX, 0x%lx) ", map->op_name, exprs[i].number, exprs[i].number2);
146
ctx->print(ctx, "0x%hhX(0x%lX, 0x%lx)", exprs[i].atom, exprs[i].number, exprs[i].number2);
153
void pst_context_init(pst_context* ctx, ucontext_t* hctx)
156
ctx->clean_print = clean_print;
158
ctx->print_expr = print_expr_block;
159
ctx->print_registers = print_registers;
160
ctx->print_stack = print_stack;
163
ctx->hcontext = hctx;
167
ctx->curr_frame = NULL;
173
void pst_context_fini(pst_context* ctx)
175
ctx->hcontext = NULL;
176
ctx->clean_print(ctx);
180
ctx->curr_frame = NULL;
187
char* pst_strdup(const char* str)
191
uint32_t len = strlen(str);
192
char* dst = (char*)allocator.alloc(&allocator, len + 1);
193
memcpy(dst, str, len);