From e62db2210d7d7e3fc2b29a0485de16c5b455ca5e Mon Sep 17 00:00:00 2001 From: Nikolai Nosov Date: Tue, 28 Jan 2020 16:44:43 +0400 Subject: [PATCH] move pst_context to separate files --- framework/common.cpp | 136 ------------------------------- framework/common.h | 54 ------------- framework/context.cpp | 152 +++++++++++++++++++++++++++++++++++ framework/context.h | 66 +++++++++++++++ framework/dwarf_operations.h | 1 + framework/registers.h | 4 + framework/sysutils.h | 1 + 7 files changed, 224 insertions(+), 190 deletions(-) create mode 100644 framework/context.cpp create mode 100644 framework/context.h diff --git a/framework/common.cpp b/framework/common.cpp index 3717c9c..1707246 100644 --- a/framework/common.cpp +++ b/framework/common.cpp @@ -19,10 +19,6 @@ #include "dwarf_operations.h" #include "registers.h" -extern SC_LogBase* logger; -extern dwarf_reg_map reg_map[]; -extern int regnum; - bool dwarf_value::get_int(int64_t& v) { switch (size) { @@ -84,138 +80,6 @@ bool dwarf_value::get_generic(uint64_t& v) return true; } -void __pst_context::print_stack(int max, uint64_t next_cfa) -{ - log(SEVERITY_DEBUG, "CFA = %#lX, NEXT_CFA = %#lX, SP = %#lX", cfa, next_cfa, sp); - clean_print(); - int i = 0; - if(cfa > sp) { - print("Args: "); - for(; i < max && (cfa - i) > sp; ++i) { - print("#%d 0x%lX ", i, *(uint64_t*)(cfa - i)); - } - } - if((cfa - i) > next_cfa) { - print("Vars: "); - for(; i < max && (cfa - i) > next_cfa; ++i) { - print("#%d 0x%lX ", i, *(uint64_t*)(cfa - i)); - } - } -} - -void __pst_context::print_registers(int from, int to) -{ - clean_print(); - for(int i = from; i < regnum && i <= to; ++i) { - unw_word_t regval; - if(!unw_get_reg(curr_frame, reg_map[i].regno, ®val)) { - print("%s: %#lX ", reg_map[i].regname, regval); - } else { - print("%s: ", reg_map[i].regname); - } - } -} - -bool __pst_context::print(const char* fmt, ...) -{ - bool nret = true; - - va_list args; - va_start(args, fmt); - int size = sizeof(buff) - offset; - int ret = vsnprintf(buff + offset, size, fmt, args); - if(ret >= size || ret < 0) { - nret = false; - } - offset += ret; - va_end(args); - - return nret; -} - -void __pst_context::log(SC_LogSeverity severity, const char* fmt, ...) -{ - uint32_t str_len = 0; - char str[PATH_MAX]; str[0] = 0; - va_list args; - va_start(args, fmt); - str_len += vsnprintf(str + str_len, sizeof(str) - str_len, fmt, args); - va_end(args); - - logger->Log(severity, "%s", str); -} - -uint32_t __pst_context::print_expr_block (Dwarf_Op *exprs, int len, char* buff, uint32_t buff_size, Dwarf_Attribute* attr) -{ - uint32_t offset = 0; - for (int i = 0; i < len; i++) { - //printf ("%s", (i + 1 < len ? ", " : "")); - const dwarf_op_map* map = find_op_map(exprs[i].atom); - if(map) { - if(map->op_num >= DW_OP_breg0 && map->op_num <= DW_OP_breg16) { - int32_t off = decode_sleb128((unsigned char*)&exprs[i].number); - int regno = map->op_num - DW_OP_breg0; - unw_word_t ptr = 0; - unw_get_reg(curr_frame, regno, &ptr); - //ptr += off; - - offset += snprintf(buff + offset, buff_size - offset, "%s(*%s%s%d) reg_value: 0x%lX", map->op_name, unw_regname(regno), off >=0 ? "+" : "", off, ptr); - } else if(map->op_num >= DW_OP_reg0 && map->op_num <= DW_OP_reg16) { - unw_word_t value = 0; - int regno = map->op_num - DW_OP_reg0; - unw_get_reg(curr_frame, regno, &value); - offset += snprintf(buff + offset, buff_size - offset, "%s(*%s) value: 0x%lX", map->op_name, unw_regname(regno), value); - } else if(map->op_num == DW_OP_GNU_entry_value) { - uint32_t value = decode_uleb128((unsigned char*)&exprs[i].number); - offset += snprintf(buff + offset, buff_size - offset, "%s(%u, ", map->op_name, value); - Dwarf_Attribute attr_mem; - if(!dwarf_getlocation_attr(attr, exprs, &attr_mem)) { - Dwarf_Op *expr; - size_t exprlen; - if (dwarf_getlocation(&attr_mem, &expr, &exprlen) == 0) { - offset += print_expr_block (expr, exprlen, buff + offset, buff_size - offset, &attr_mem); - offset += snprintf(buff + offset, buff_size - offset, ") "); - } else { - log(SEVERITY_ERROR, "Failed to get DW_OP_GNU_entry_value attr location"); - } - } else { - log(SEVERITY_ERROR, "Failed to get DW_OP_GNU_entry_value attr expression"); - } - } else if(map->op_num == DW_OP_stack_value) { - offset += snprintf(buff + offset, buff_size - offset, "%s", map->op_name); - } else if(map->op_num == DW_OP_plus_uconst) { - uint32_t value = decode_uleb128((unsigned char*)&exprs[i].number); - offset += snprintf(buff + offset, buff_size - offset, "%s(+%u) ", map->op_name, value); - } else if(map->op_num == DW_OP_bregx) { - uint32_t regno = decode_uleb128((unsigned char*)&exprs[i].number); - int32_t off = decode_sleb128((unsigned char*)&exprs[i].number2); - unw_word_t ptr = 0; - unw_get_reg(curr_frame, regno, &ptr); - //ptr += off; - offset += snprintf(buff + offset, buff_size - offset, "%s(%s%s%d) reg_value = 0x%lX", map->op_name, unw_regname(regno), off >= 0 ? "+" : "", off, ptr); - } else if(map->op_num == DW_OP_regx) { - int32_t reg = decode_sleb128((unsigned char*)&exprs[i].number); - - unw_word_t value = 0; - unw_get_reg(curr_frame, reg, &value); - - offset += snprintf(buff + offset, buff_size - offset, "%s(%s) value = 0x%lX", map->op_name, unw_regname(reg), value); - } else if(map->op_num == DW_OP_addr) { - offset += snprintf(buff + offset, buff_size - offset, "%s value = %p", map->op_name, (void*)exprs[i].number); - } else if(map->op_num == DW_OP_fbreg) { - int32_t off = decode_sleb128((unsigned char*)&exprs[i].number); - offset += snprintf(buff + offset, buff_size - offset, "%s(SP%s%d) ", map->op_name, off >=0 ? "+" : "", off); - } else { - offset += snprintf(buff + offset, buff_size - offset, "%s(0x%lX, 0x%lx) ", map->op_name, exprs[i].number, exprs[i].number2); - } - } else { - offset += snprintf(buff + offset, buff_size - offset, "0x%hhX(0x%lX, 0x%lx)", exprs[i].atom, exprs[i].number, exprs[i].number2); - } - } - - return offset; -} - bool is_location_form(int form) { if (form == DW_FORM_block1 || form == DW_FORM_block2 || form == DW_FORM_block4 || form == DW_FORM_block || diff --git a/framework/common.h b/framework/common.h index b4523f8..e4aa50d 100644 --- a/framework/common.h +++ b/framework/common.h @@ -1,61 +1,7 @@ #pragma once -#include -#include -#include -#include - -#include "logger/log.h" -#include "linkedlist.h" - #define USE_LIBUNWIND -typedef struct __pst_context { - __pst_context(ucontext_t* hctx) : hcontext(hctx) - { - clean_print(); - base_addr = 0; - sp = 0; - cfa = 0; - curr_frame = NULL; - next_frame = NULL; - frame = NULL; - dwfl = NULL; - module = NULL; - } - - bool print(const char* fmt, ...); - void log(SC_LogSeverity severity, const char*fmt, ...); - uint32_t print_expr_block(Dwarf_Op *exprs, int len, char* buff, uint32_t buff_size, Dwarf_Attribute* attr = 0); - void print_registers(int from, int to); - void print_stack(int max, uint64_t next_cfa); - void clean_print() { - buff[0] = 0; - offset = 0; - } - - const char* get_print() { - return buff; - } - - ucontext_t* hcontext; // context of signal handler - unw_context_t context; // context of stack trace - unw_cursor_t cursor; - unw_cursor_t* curr_frame; // callee libunwind frame - unw_cursor_t* next_frame; // caller libunwind frame - Dwarf_Addr base_addr; // base address where process loaded - - Dwarf_Addr sp; - Dwarf_Addr cfa; - Dwarf_Frame* frame; // currently examined libdwfl frame - Dwfl* dwfl; // DWARF context - Dwfl_Module* module; // currently processed CU - -protected: - char buff[8192]; // stack trace buffer - uint32_t offset; // offset in the 'buff' -} pst_context; - int32_t decode_sleb128(uint8_t *sleb128); uint32_t decode_uleb128(uint8_t *uleb128); diff --git a/framework/context.cpp b/framework/context.cpp new file mode 100644 index 0000000..57ddd20 --- /dev/null +++ b/framework/context.cpp @@ -0,0 +1,152 @@ +/* + * context.cpp + * + * Created on: Jan 28, 2020 + * Author: nnosov + */ + +#include +#include + +#include "context.h" +#include "registers.h" +#include "dwarf_operations.h" + + +extern SC_LogBase* logger; +extern dwarf_reg_map reg_map[]; +extern int regnum; + +void __pst_context::print_stack(int max, uint64_t next_cfa) +{ + log(SEVERITY_DEBUG, "CFA = %#lX, NEXT_CFA = %#lX, SP = %#lX", cfa, next_cfa, sp); + clean_print(); + int i = 0; + if(cfa > sp) { + print("Args: "); + for(; i < max && (cfa - i) > sp; ++i) { + print("#%d 0x%lX ", i, *(uint64_t*)(cfa - i)); + } + } + if((cfa - i) > next_cfa) { + print("Vars: "); + for(; i < max && (cfa - i) > next_cfa; ++i) { + print("#%d 0x%lX ", i, *(uint64_t*)(cfa - i)); + } + } +} + +void __pst_context::print_registers(int from, int to) +{ + clean_print(); + for(int i = from; i < regnum && i <= to; ++i) { + unw_word_t regval; + if(!unw_get_reg(curr_frame, reg_map[i].regno, ®val)) { + print("%s: %#lX ", reg_map[i].regname, regval); + } else { + print("%s: ", reg_map[i].regname); + } + } +} + +bool __pst_context::print(const char* fmt, ...) +{ + bool nret = true; + + va_list args; + va_start(args, fmt); + int size = sizeof(buff) - offset; + int ret = vsnprintf(buff + offset, size, fmt, args); + if(ret >= size || ret < 0) { + nret = false; + } + offset += ret; + va_end(args); + + return nret; +} + +void __pst_context::log(SC_LogSeverity severity, const char* fmt, ...) +{ + uint32_t str_len = 0; + char str[PATH_MAX]; str[0] = 0; + va_list args; + va_start(args, fmt); + str_len += vsnprintf(str + str_len, sizeof(str) - str_len, fmt, args); + va_end(args); + + logger->Log(severity, "%s", str); +} + +uint32_t __pst_context::print_expr_block (Dwarf_Op *exprs, int len, char* buff, uint32_t buff_size, Dwarf_Attribute* attr) +{ + uint32_t offset = 0; + for (int i = 0; i < len; i++) { + //printf ("%s", (i + 1 < len ? ", " : "")); + const dwarf_op_map* map = find_op_map(exprs[i].atom); + if(map) { + if(map->op_num >= DW_OP_breg0 && map->op_num <= DW_OP_breg16) { + int32_t off = decode_sleb128((unsigned char*)&exprs[i].number); + int regno = map->op_num - DW_OP_breg0; + unw_word_t ptr = 0; + unw_get_reg(curr_frame, regno, &ptr); + //ptr += off; + + offset += snprintf(buff + offset, buff_size - offset, "%s(*%s%s%d) reg_value: 0x%lX", map->op_name, unw_regname(regno), off >=0 ? "+" : "", off, ptr); + } else if(map->op_num >= DW_OP_reg0 && map->op_num <= DW_OP_reg16) { + unw_word_t value = 0; + int regno = map->op_num - DW_OP_reg0; + unw_get_reg(curr_frame, regno, &value); + offset += snprintf(buff + offset, buff_size - offset, "%s(*%s) value: 0x%lX", map->op_name, unw_regname(regno), value); + } else if(map->op_num == DW_OP_GNU_entry_value) { + uint32_t value = decode_uleb128((unsigned char*)&exprs[i].number); + offset += snprintf(buff + offset, buff_size - offset, "%s(%u, ", map->op_name, value); + Dwarf_Attribute attr_mem; + if(!dwarf_getlocation_attr(attr, exprs, &attr_mem)) { + Dwarf_Op *expr; + size_t exprlen; + if (dwarf_getlocation(&attr_mem, &expr, &exprlen) == 0) { + offset += print_expr_block (expr, exprlen, buff + offset, buff_size - offset, &attr_mem); + offset += snprintf(buff + offset, buff_size - offset, ") "); + } else { + log(SEVERITY_ERROR, "Failed to get DW_OP_GNU_entry_value attr location"); + } + } else { + log(SEVERITY_ERROR, "Failed to get DW_OP_GNU_entry_value attr expression"); + } + } else if(map->op_num == DW_OP_stack_value) { + offset += snprintf(buff + offset, buff_size - offset, "%s", map->op_name); + } else if(map->op_num == DW_OP_plus_uconst) { + uint32_t value = decode_uleb128((unsigned char*)&exprs[i].number); + offset += snprintf(buff + offset, buff_size - offset, "%s(+%u) ", map->op_name, value); + } else if(map->op_num == DW_OP_bregx) { + uint32_t regno = decode_uleb128((unsigned char*)&exprs[i].number); + int32_t off = decode_sleb128((unsigned char*)&exprs[i].number2); + unw_word_t ptr = 0; + unw_get_reg(curr_frame, regno, &ptr); + //ptr += off; + offset += snprintf(buff + offset, buff_size - offset, "%s(%s%s%d) reg_value = 0x%lX", map->op_name, unw_regname(regno), off >= 0 ? "+" : "", off, ptr); + } else if(map->op_num == DW_OP_regx) { + int32_t reg = decode_sleb128((unsigned char*)&exprs[i].number); + + unw_word_t value = 0; + unw_get_reg(curr_frame, reg, &value); + + offset += snprintf(buff + offset, buff_size - offset, "%s(%s) value = 0x%lX", map->op_name, unw_regname(reg), value); + } else if(map->op_num == DW_OP_addr) { + offset += snprintf(buff + offset, buff_size - offset, "%s value = %p", map->op_name, (void*)exprs[i].number); + } else if(map->op_num == DW_OP_fbreg) { + int32_t off = decode_sleb128((unsigned char*)&exprs[i].number); + offset += snprintf(buff + offset, buff_size - offset, "%s(SP%s%d) ", map->op_name, off >=0 ? "+" : "", off); + } else { + offset += snprintf(buff + offset, buff_size - offset, "%s(0x%lX, 0x%lx) ", map->op_name, exprs[i].number, exprs[i].number2); + } + } else { + offset += snprintf(buff + offset, buff_size - offset, "0x%hhX(0x%lX, 0x%lx)", exprs[i].atom, exprs[i].number, exprs[i].number2); + } + } + + return offset; +} + + diff --git a/framework/context.h b/framework/context.h new file mode 100644 index 0000000..7dc151b --- /dev/null +++ b/framework/context.h @@ -0,0 +1,66 @@ +/* + * context.h + * + * Created on: Jan 28, 2020 + * Author: nnosov + */ + +#ifndef FRAMEWORK_CONTEXT_H_ +#define FRAMEWORK_CONTEXT_H_ + +#include +#include +#include +#include +#include + +#include "logger/log.h" + +typedef struct __pst_context { + __pst_context(ucontext_t* hctx) : hcontext(hctx) + { + clean_print(); + base_addr = 0; + sp = 0; + cfa = 0; + curr_frame = NULL; + next_frame = NULL; + frame = NULL; + dwfl = NULL; + module = NULL; + } + + bool print(const char* fmt, ...); + void log(SC_LogSeverity severity, const char*fmt, ...); + uint32_t print_expr_block(Dwarf_Op *exprs, int len, char* buff, uint32_t buff_size, Dwarf_Attribute* attr = 0); + void print_registers(int from, int to); + void print_stack(int max, uint64_t next_cfa); + void clean_print() { + buff[0] = 0; + offset = 0; + } + + const char* get_print() { + return buff; + } + + ucontext_t* hcontext; // context of signal handler + unw_context_t context; // context of stack trace + unw_cursor_t cursor; + unw_cursor_t* curr_frame; // callee libunwind frame + unw_cursor_t* next_frame; // caller libunwind frame + Dwarf_Addr base_addr; // base address where process loaded + + Dwarf_Addr sp; + Dwarf_Addr cfa; + Dwarf_Frame* frame; // currently examined libdwfl frame + Dwfl* dwfl; // DWARF context + Dwfl_Module* module; // currently processed CU + +protected: + char buff[8192]; // stack trace buffer + uint32_t offset; // offset in the 'buff' +} pst_context; + + +#endif /* FRAMEWORK_CONTEXT_H_ */ diff --git a/framework/dwarf_operations.h b/framework/dwarf_operations.h index 8d84462..1548a82 100644 --- a/framework/dwarf_operations.h +++ b/framework/dwarf_operations.h @@ -5,6 +5,7 @@ #include "common.h" #include "linkedlist.h" #include "sysutils.h" +#include "context.h" typedef enum { DWARF_TYPE_INVALID = 0, // no type diff --git a/framework/registers.h b/framework/registers.h index b5bc7d9..cfb6d05 100644 --- a/framework/registers.h +++ b/framework/registers.h @@ -1,7 +1,11 @@ #pragma once #include +#include +#include "linkedlist.h" + +#include "context.h" typedef struct __dwarf_reg_map { int regno; // platform-dependent register number diff --git a/framework/sysutils.h b/framework/sysutils.h index e99bb7f..e3eb27a 100644 --- a/framework/sysutils.h +++ b/framework/sysutils.h @@ -23,6 +23,7 @@ #include #include "common.h" +#include "context.h" #include "dictionary.h" #include "data_entry.h"