static print_base_disp_for_lea(file_t file, opnd_t opnd){ /* [base + index * scale + disp] */ dr_fprintf(file, " base - %d %s\n", opnd_get_base(opnd), get_register_name(opnd_get_base(opnd))); dr_fprintf(file, " index - %d %s\n", opnd_get_index(opnd), get_register_name(opnd_get_index(opnd))); dr_fprintf(file, "reg - %d\n", opnd_is_reg(opnd_create_reg(opnd_get_index(opnd)))); dr_fprintf(file, " scale - %d\n", opnd_get_scale(opnd)); dr_fprintf(file, " disp - %d\n", opnd_get_disp(opnd)); }
QString Device::entryAsString(void *e) const { const log_entry *entry = (Device::log_entry*) e; QTime mstime = QTime(0, 0).addMSecs(entry->time / 1000); QString ret; ret = mstime.toString("hh:mm:ss.zzz") + QString().sprintf(".%03d\t", entry->time % 1000); if (!entry->is_irq) { ret += entry->is_write ? "writing" : "reading"; ret += QString().sprintf("%d 0x%08X ", entry->rw_size, entry->is_write ? entry->new_value : entry->value); ret += (entry->is_write ? "to " : "from "); ret += get_register_name(*entry); ret += QString().sprintf("\tcpu[%d] @0x%08X", entry->cpu_id, entry->cpu_pc); } else { ret += QString().sprintf("irq %u\tstatus: %u",entry->offset, entry->value); } return ret; }
void print_fatal_info(int sig, siginfo_t *siginfo, void *context) { #ifdef HAVE_SYS_UCONTEXT_H #if defined(REG_EIP) || defined(REG_RIP) ucontext_t *uctx = (ucontext_t *)context; #endif /* look for GET_PC() macro in sigcontextinfo.h files */ /* of glibc if you wish to add more CPU architectures */ # if defined(REG_EIP) /* i386 */ # define ZBX_GET_REG(uctx, reg) (uctx)->uc_mcontext.gregs[reg] # define ZBX_GET_PC(uctx) ZBX_GET_REG(uctx, REG_EIP) # elif defined(REG_RIP) /* x86_64 */ # define ZBX_GET_REG(uctx, reg) (uctx)->uc_mcontext.gregs[reg] # define ZBX_GET_PC(uctx) ZBX_GET_REG(uctx, REG_RIP) # endif #endif /* HAVE_SYS_UCONTEXT_H */ #ifdef HAVE_EXECINFO_H # define ZBX_BACKTRACE_SIZE 60 char **bcktrc_syms; void *bcktrc[ZBX_BACKTRACE_SIZE]; int bcktrc_sz; #endif /* HAVE_EXECINFO_H */ int i; FILE *fd; zabbix_log(LOG_LEVEL_CRIT, "====== Fatal information: ======"); #ifdef HAVE_SYS_UCONTEXT_H #ifdef ZBX_GET_PC zabbix_log(LOG_LEVEL_CRIT, "Program counter: %p", ZBX_GET_PC(uctx)); zabbix_log(LOG_LEVEL_CRIT, "=== Registers: ==="); for (i = 0; i < NGREG; i++) zabbix_log(LOG_LEVEL_CRIT, "%-7s = %16lx = %20lu = %20ld", get_register_name(i), ZBX_GET_REG(uctx, i), ZBX_GET_REG(uctx, i), ZBX_GET_REG(uctx, i)); #ifdef REG_EBP /* dump a bit of stack frame for i386 */ zabbix_log(LOG_LEVEL_CRIT, "=== Stack frame: ==="); for (i = 16; i >= 2; i--) zabbix_log(LOG_LEVEL_CRIT, "+0x%02x(%%ebp) = ebp + %2d = %08x = %10u = %11d%s", i * ZBX_PTR_SIZE, i * ZBX_PTR_SIZE, *(unsigned int *)((void *)ZBX_GET_REG(uctx, REG_EBP) + i * ZBX_PTR_SIZE), *(unsigned int *)((void *)ZBX_GET_REG(uctx, REG_EBP) + i * ZBX_PTR_SIZE), *(unsigned int *)((void *)ZBX_GET_REG(uctx, REG_EBP) + i * ZBX_PTR_SIZE), i == 2 ? " <--- call arguments" : ""); zabbix_log(LOG_LEVEL_CRIT, "+0x%02x(%%ebp) = ebp + %2d = %08x%28s<--- return address", ZBX_PTR_SIZE, ZBX_PTR_SIZE, *(unsigned int *)((void *)ZBX_GET_REG(uctx, REG_EBP) + ZBX_PTR_SIZE), ""); zabbix_log(LOG_LEVEL_CRIT, " (%%ebp) = ebp = %08x%28s<--- saved ebp value", *(unsigned int *)((void *)ZBX_GET_REG(uctx, REG_EBP)), ""); for (i = 1; i <= 16; i++) zabbix_log(LOG_LEVEL_CRIT, "-0x%02x(%%ebp) = ebp - %2d = %08x = %10u = %11d%s", i * ZBX_PTR_SIZE, i * ZBX_PTR_SIZE, *(unsigned int *)((void *)ZBX_GET_REG(uctx, REG_EBP) - i * ZBX_PTR_SIZE), *(unsigned int *)((void *)ZBX_GET_REG(uctx, REG_EBP) - i * ZBX_PTR_SIZE), *(unsigned int *)((void *)ZBX_GET_REG(uctx, REG_EBP) - i * ZBX_PTR_SIZE), i == 1 ? " <--- local variables" : ""); #endif /* REG_EBP */ #else zabbix_log(LOG_LEVEL_CRIT, "program counter not available for this architecture"); zabbix_log(LOG_LEVEL_CRIT, "=== Registers: ==="); zabbix_log(LOG_LEVEL_CRIT, "register dump not available for this architecture"); #endif /* ZBX_GET_PC */ #endif /* HAVE_SYS_UCONTEXT_H */ zabbix_log(LOG_LEVEL_CRIT, "=== Backtrace: ==="); #ifdef HAVE_EXECINFO_H bcktrc_sz = backtrace(bcktrc, ZBX_BACKTRACE_SIZE); bcktrc_syms = backtrace_symbols(bcktrc, bcktrc_sz); if (NULL == bcktrc_syms) { zabbix_log(LOG_LEVEL_CRIT, "error in backtrace_symbols(): %s", zbx_strerror(errno)); for (i = 0; i < bcktrc_sz; i++) zabbix_log(LOG_LEVEL_CRIT, "%d: %p", bcktrc_sz - i - 1, bcktrc[i]); } else { for (i = 0; i < bcktrc_sz; i++) zabbix_log(LOG_LEVEL_CRIT, "%d: %s", bcktrc_sz - i - 1, bcktrc_syms[i]); zbx_free(bcktrc_syms); } #else zabbix_log(LOG_LEVEL_CRIT, "backtrace not available for this platform"); #endif /* HAVE_EXECINFO_H */ zabbix_log(LOG_LEVEL_CRIT, "=== Memory map: ==="); if (NULL != (fd = fopen("/proc/self/maps", "r"))) { char line[1024]; while (NULL != fgets(line, sizeof(line), fd)) { if (line[0] != '\0') line[strlen(line) - 1] = '\0'; /* remove trailing '\n' */ zabbix_log(LOG_LEVEL_CRIT, "%s", line); } zbx_fclose(fd); } else zabbix_log(LOG_LEVEL_CRIT, "memory map not available for this platform"); #ifdef ZBX_GET_PC zabbix_log(LOG_LEVEL_CRIT, "================================"); zabbix_log(LOG_LEVEL_CRIT, "Please consider attaching a disassembly listing to your bug report."); zabbix_log(LOG_LEVEL_CRIT, "This listing can be produced with, e.g., objdump -DSswx %s.", progname); #endif zabbix_log(LOG_LEVEL_CRIT, "================================"); }
static void callback(reg_id_t reg, int displacement, reg_id_t destReg, int opcode, app_pc addr){ int r, s; const char * destRegName = get_register_name(destReg); int regId = atoi(destRegName + 3 * sizeof(char)); dr_mcontext_t mcontext; memset(&mcontext, 0, sizeof(dr_mcontext_t)); mcontext.flags = DR_MC_ALL; mcontext.size = sizeof(dr_mcontext_t); bool result = dr_get_mcontext(dr_get_current_drcontext(), &mcontext); reg_t mem_reg; if(reg == DR_REG_RAX) mem_reg = mcontext.rax; else if(reg == DR_REG_RBP) mem_reg = mcontext.rbp; else if(reg == DR_REG_RBX) mem_reg = mcontext.rbx; else if(reg == DR_REG_RCX) mem_reg = mcontext.rcx; else if(reg == DR_REG_RDI) mem_reg = mcontext.rdi; else if(reg == DR_REG_RDX) mem_reg = mcontext.rdx; else if(reg == DR_REG_RSI) mem_reg = mcontext.rsi; else if(reg == DR_REG_RSP) mem_reg = mcontext.rsp; else mem_reg = NULL; //deal with a null case, rip enum doesn't exist int bits = 0; double loss = 0; double lossD = 0; if(is_single_precision_instr(opcode)){ float op1, op2; // printf("Mem reg contents: %f\n", *(float*)(mem_reg + displacement)); op2 = *(float*)(mem_reg + displacement); // for(r=0; r<16; ++r) // for(s=0; s<4; ++s) // printf("reg %i.%i: %f\n", r, s, // *((float*) &mcontext.ymm[r].u32[s])); op1 = *((float*) &mcontext.ymm[regId].u32[0]); // dr_fprintf(logF, "%d: %f %f\n",opcode, op1, op2); int exp1, exp2; float mant1, mant2; mant1 = frexpf(op1, &exp1); mant2 = frexpf(op2, &exp2); bits = abs(exp1-exp2); double dop1 = op1; double dop2 = op2; if(opcode == OP_addss){ double dadd = dop1 + dop2; float fadd = op1 + op2; lossD = dadd - fadd; //printf("double %.13lf float %.13f\n", dadd, fadd); } else{ double dsub = dop1 - dop2; float fsub = op1 - op2; lossD = dsub - fsub; } // printf("diff of double and float is %.13lf\n", lossD); } else{ double op1, op2; printf("Mem reg contents: %.13lf\n", *(double*)(mem_reg + displacement)); op2 = *(double*)(mem_reg + displacement); // for(r=0; r<16; ++r) // for(s=0; s<2; ++s) // printf("reg %i.%i: %lf\n", r, s, // *((double*) &mcontext.ymm[r].u64[s])); op1 = *((double*) &mcontext.ymm[regId].u64[0]); // dr_fprintf(logF, "%d: %.13lf %.13lf\n",opcode, op1, op2); int exp1, exp2; double mant1, mant2; mant1 = frexp(op1, &exp1); mant2 = frexp(op2, &exp2); bits = abs(exp1-exp2); printf("op1 %.13lf mantissa %.13lf exp %d\n", op1, mant1, exp1); printf("op2 %.13lf mantissa %.13lf exp %d\n", op2, mant2, exp2); } print_address(addr, bits, loss, lossD); }
static void getRegReg(reg_id_t r1, reg_id_t r2, int opcode, app_pc addr){ const char * r1Name = get_register_name(r1); const char * r2Name = get_register_name(r2); int s1 = atoi(r1Name + 3 * sizeof(char)); int s2 = atoi(r2Name + 3 * sizeof(char)); dr_mcontext_t mcontext; memset(&mcontext, 0, sizeof(dr_mcontext_t)); mcontext.flags = DR_MC_MULTIMEDIA; mcontext.size = sizeof(dr_mcontext_t); bool result = dr_get_mcontext(dr_get_current_drcontext(), &mcontext); int r, s; int bits = 0; double loss = 0; double lossD = 0; if(is_single_precision_instr(opcode)){ float op1, op2; // for(r=0; r<16; ++r) // for(s=0; s<4; ++s) // printf("reg %i.%i: %f\n", r, s, // *((float*) &mcontext.ymm[r].u32[s])); op1 = *((float*) &mcontext.ymm[s1].u32[0]); op2 = *((float*) &mcontext.ymm[s2].u32[0]); // dr_fprintf(logF, "%d: %f %f\n",opcode, op1, op2); int exp1, exp2; float mant1, mant2; mant1 = frexpf(op1, &exp1); mant2 = frexpf(op2, &exp2); bits = abs(exp1-exp2); double dop1 = op1; double dop2 = op2; if(opcode == OP_addss){ double dadd = dop1 + dop2; float fadd = op1 + op2; lossD = dadd - fadd; // printf("double %.13lf float %.13f\n", dadd, fadd); } else{ double dsub = dop1 - dop2; float fsub = op1 - op2; lossD = dsub - fsub; } // printf("diff of double and float is %.13lf\n", lossD); } else{ double op1, op2; // for(r=0; r<16; ++r) // for(s=0; s<2; ++s) // printf("reg %i.%i: %f\n", r, s, // *((double*) &mcontext.ymm[r].u64[s])); op1 = *((double*) &mcontext.ymm[s1].u64[0]); op2 = *((double*) &mcontext.ymm[s2].u64[0]); // dr_fprintf(logF, "%d: %.13lf %.13lf\n",opcode, op1, op2); int exp1, exp2; double mant1, mant2; mant1 = frexp(op1, &exp1); mant2 = frexp(op2, &exp2); bits = abs(exp1-exp2); printf("op1 %.13lf mantissa %.13lf exp %d\n", op1, mant1, exp1); printf("op2 %.13lf mantissa %.13lf exp %d\n", op2, mant2, exp2); } print_address(addr, bits, loss, lossD); }
QVariant Device::data(const QModelIndex &index, int role) const { log_entry entry; QTime mstime; int div = 1; Q_ASSERT(index.row() < m_log.size()); switch (role) { case Qt::EditRole: switch ( index.column() ) { case Device::REGISTER: entry = m_log.read( index.row() ); return get_register_name(entry) + QString().sprintf(" 0x%08X", entry.offset + (m_base >= 0x50000000 ? m_base : 0)); default: break; } case Qt::DisplayRole: entry = m_log.read( index.row() ); switch ( index.column() ) { case Device::REGISTER: if (entry.is_irq) return QString("IRQ ") + QString::number(entry.offset); if (entry.is_error) { const char *format = entry.is_write ? "write%d to 0x%X" : "read%d 0x%X"; return QString().sprintf(format, entry.rw_size, entry.offset); } if (entry.clk_disabled || entry.in_reset) return get_register_name(entry) + " clk_enb: " + QString::number(!entry.clk_disabled) + " rst: " + QString::number(entry.in_reset); return get_register_name(entry); case Device::VALUE: if (entry.is_irq) return QString("STATUS ") + QString::number(entry.value); return QString().sprintf("0x%08X", entry.is_write? entry.new_value : entry.value); case Device::TIME: mstime = QTime(0, 0).addMSecs(entry.time / 1000); return mstime.toString("hh:mm:ss.zzz") + QString().sprintf(".%03d", entry.time % 1000); case Device::CPU_PC: return QString().sprintf("[%d] @0x%08X", entry.cpu_id, entry.cpu_pc); default: break; } break; case Qt::BackgroundRole: entry = m_log.read( index.row() ); if (m_regFilter.length() && get_register_name(entry).indexOf(m_regFilter) == -1) div = 2; if (index.column() == Device::CPU_PC) return QVariant(); if (entry.is_irq) { if (entry.value) return QColor(255 / div, 192 / div, 255 / div); else return QColor(192 / div, 255 / div, 255 / div); } if (entry.is_error) return QColor(255 / div, 150 / div, 150 / div); // light red if (index.column() == Device::REGISTER) { if (entry.clk_disabled || entry.in_reset) return QColor(255 / div, 150 / div, 150 / div); // light red } if (!entry.is_write) return QColor(200 / div, 255 / div, 200 / div); // light green if (entry.value != entry.new_value) return QColor(0xf4 / div, 0xa7 / div, 0); // brown return QColor(255 / div, 255 / div, 150 / div); // light yellow case Qt::ToolTipRole: switch ( index.column() ) { case Device::TIME: entry = m_log.read( index.row() ); return QString::number(entry.time) + "us"; case Device::REGISTER: entry = m_log.read( index.row() ); return QString().sprintf("0x%08X", entry.offset); default: break; } break; case Qt::ForegroundRole: if (index.column() != Device::CPU_PC) return QColor(Qt::black); break; default: break; } return QVariant(); }
void Device::write_log(log_entry &entry) { if (!entry.is_irq) { update_internal(entry); } bool log_is_full = m_log.write(entry); emit layoutChanged(); if (log_is_full) { emit itemInserted(); } if (entry.is_error) { m_dev_errs_nb++; m_errs_stat_dirty = true; updateName(); emit ErrorUnknownReg(m_name, entry); emit errorStatUpdated(this->id); } else if (!entry.is_irq) { if (entry.is_write && is_undef_changed(entry.offset, entry.value, entry.new_value)) { QString text = "changing undefined bits "; text += get_register_name(entry) + " "; text += QString().sprintf("0x%08X -> 0x%08X", entry.value, entry.new_value) + " "; text += QString().sprintf("cpu=0x%08X", entry.cpu_pc); emit ErrorCustom(m_name, text, entry.time); } if (entry.clk_disabled || entry.in_reset) { m_dev_errs_nb++; m_errs_stat_dirty = true; updateName(); emit errorStatUpdated(this->id); } } if (entry.is_irq) { m_irq_act = !!entry.value; m_dev_irqs_nb++; m_irqs_stat_dirty = true; } else if (entry.is_write) { m_dev_writes_nb++; m_writes_stat_dirty = true; } else { m_dev_reads_nb++; m_reads_stat_dirty = true; } if (!m_stats_changed) { m_stats_changed = true; emit firstTimeStatUpdated(this->id); } if (!update_dev_stats_timer.isActive()) { update_dev_stats_timer.start(300); } blink_reset_timer.start(1500); if (m_record_dev) m_record_dev->write_log(entry); }