?? htanaly.cc
字號:
/* * HT Editor * htanaly.cc * * Copyright (C) 1999-2002 Sebastian Biallas (sb@biallas.net) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <cstdlib>#include <cstring>#include <memory>#include "analy.h"#include "analy_names.h"#include "log.h"#include "htanaly.h"#include "htctrl.h" // FIXME: globalerror#include "htdialog.h"#include "htdisasm.h"#include "hthist.h"#include "htidle.h"#include "htiobox.h"#include "keyb.h"#include "htmenu.h"#include "htsearch.h"#include "strtools.h"#include "httag.h"#include "httree.h"#include "language.h"#include "textedit.h"#include "textfile.h"#include "tools.h"#include "snprintf.h"#include "syntax.h"#include "out.h"#include "out_ht.h"#include "out_txt.h"#include "store.h"extern "C" {#include "evalx.h"}/* FIXME: test *///#include "srt.h"#include "out_html.h"#include "out_sym.h"/* * AnalyserInformation */void AnalyserInformation::init(Bounds *b, ht_aviewer *a){ analy = a; assert(a); ht_statictext::init(b, 0, align_left); register_idle_object(this); idle();}void AnalyserInformation::done(){ unregister_idle_object(this); ht_statictext::done();}int AnalyserInformation::gettext(char *buf, int maxlen){ return ht_snprintf(buf, maxlen, "Analyser statistics:\n" "====================\n\n" "Type: %s\nFile: %y\n" "Using disassembler: %s\n\n" "Known locations: %d\n" "Known symbols: %d\n\n", atype, &aname, adis, addrs, labels);}bool AnalyserInformation::idle(){ if (analy && analy->analy) { addrs = analy->analy->getLocationCount(); labels = analy->analy->getSymbolCount(); atype = analy->analy->getType(); analy->analy->getName(aname); if (analy->analy->disasm) { adis = analy->analy->disasm->getName(); } else { adis = "?"; } dirtyview(); } return false;}/* * SymbolBox */void SymbolBox::init(Bounds *b, Analyser *Analy){ analy = Analy; ht_listbox::init(b); str = ht_malloc(1024); symbols = analy->getSymbolCount(); idle_count = 1;}void SymbolBox::done(){ free(str); ht_listbox::done();}int SymbolBox::calcCount(){ return analy->getSymbolCount();}int SymbolBox::cursorAdjust(){ Symbol *l = ((Symbol *)getFirst()); if (!l) return 0; return l->location->addr->stringSize()+10;}int SymbolBox::estimateEntryPos(void *entry){ return 0;}void *SymbolBox::getFirst(){ return analy->enumSymbols(NULL);}void *SymbolBox::getLast(){ return analy->enumSymbolsReverse(NULL);}void *SymbolBox::getNext(void *entry){ if (!entry) return NULL; return analy->enumSymbols((Symbol *)entry);}void *SymbolBox::getPrev(void *entry){ if (!entry) return NULL; return analy->enumSymbolsReverse((Symbol *)entry);}const char *SymbolBox::getStr(int col, void *entry){ if (!entry) return NULL; Symbol *l = ((Symbol *)entry); switch (col) { case 0: global_analyser_address_string_format = ADDRESS_STRING_FORMAT_LEADING_WHITESPACE; ht_snprintf(str, 1024, "%y", l->location->addr); break; case 1: ht_snprintf(str, 1024, "%s", label_type_short(l->type)); break; case 2: ht_snprintf(str, 1024, "%s", l->name); break; } return str;}bool SymbolBox::idle(){ if ((idle_count % 500)==0) { update(); redraw(); symbols = analy->getSymbolCount(); idle_count = 1; return 1; } idle_count++; return 0;}int SymbolBox::numColumns(){ return 3;}void *SymbolBox::quickfind(const char *s){ Symbol *tmp = analy->getSymbolByName(s); if (tmp) return tmp; tmp = analy->enumSymbolsByName(s); if (tmp) { int slen = strlen(s); int tlen = strlen(tmp->name); if (slen > tlen) return NULL; if (ht_strncmp(tmp->name, s, slen)==0) return tmp; return NULL; } else { return NULL; }}char *SymbolBox::quickfindCompletition(const char *s){ if (analy->getSymbolByName(s)) { return ht_strdup(s); } Symbol *tmp = analy->enumSymbolsByName(s); if (!tmp) { return ht_strdup(s); } Symbol *tmp2 = analy->enumSymbols(tmp); if (!tmp2) { return ht_strdup(tmp->name); } int slen = strlen(s); if (!ht_strncmp(tmp->name, tmp2->name, slen)==0) { return ht_strdup(tmp->name); } char *res = ht_malloc(1024); // buffer bla strcpy(res, tmp->name); while (tmp2 && (ht_strncmp(tmp2->name, s, slen)==0)) {// fprintf(stdout, "while(%s, %s, %d)\n", tmp2->name, s, slen); int a = ht_strccomm(res, tmp2->name); res[a] = 0; tmp2 = analy->enumSymbols(tmp2); } return res;}/* * CLASS CallChain */void CallChain::init(Bounds *b, Analyser *Analy, Address *a, char *desc){ ht_treeview::init(b, desc); VIEW_DEBUG_NAME("CallChain"); analy = Analy; root = createNode(a);}void CallChain_done(CallChainNode *n){ while (n) { CallChain_done(n->child); CallChainNode *temp = n->next; free(n); n = temp; }}void CallChain::done(){ CallChain_done(root); ht_treeview::done();}void CallChain::adjust(void *node, bool expand){ ((CallChainNode*)node)->expanded = expand;}CallChainNode *CallChain::createNode(Address *a){ CallChainNode *n = ht_malloc(sizeof(CallChainNode)); n->next = NULL; n->prev = NULL; n->child = NULL; n->examined = false; n->xa = a->clone(); n->faddr = analy->getFunctionByAddress(a); assert(n->faddr); n->fa = n->faddr->addr; n->expanded = false; return n;}void CallChain::examineNode(CallChainNode *n){ n->examined = true; if (has_children(n)) { Container *x_tree = n->faddr->xrefs; assert(x_tree); ObjHandle oh = x_tree->findFirst(); AddrXRef *x = (AddrXRef *)x_tree->get(oh); assert(x); CallChainNode *nn = n->child = createNode(x->addr); while ((oh = x_tree->findNext(oh)) != invObjHandle) { x = (AddrXRef *)x_tree->get(oh); nn->next = createNode(x->addr); nn = nn->next; } }}void *CallChain::get_child(void *node, int i){ CallChainNode *p; if (node) { if (!((CallChainNode *)node)->examined) examineNode((CallChainNode*)node); p = ((CallChainNode *)node)->child; } else { p = root; } while (p && (--i)) p = p->next; return p;}void *CallChain::get_next_node(void *node){ return ((CallChainNode*)node)->next;}void *CallChain::get_prev_node(void *node){ return ((CallChainNode*)node)->prev;}void *CallChain::get_root(){ return root;}char *CallChain::get_text(void *node){ static char stupid[1024]; // FIXME: static var CallChainNode *n = (CallChainNode*)node; int d = 0; n->xa->difference(d, n->faddr->addr); char sign = '+'; if (d < 0) { d = -d; sign = '-'; } global_analyser_address_string_format = ADDRESS_STRING_FORMAT_COMPACT | ADDRESS_STRING_FORMAT_ADD_0X; ht_snprintf(stupid, sizeof stupid, "%s%c%x (%y)", n->faddr->label ? n->faddr->label->name : "unknown", sign, d, n->xa ); return stupid;}bool CallChain::has_children(void *node){ return ((CallChainNode*)node)->faddr->xrefs != NULL;}bool CallChain::is_expanded(void *node){ return ((CallChainNode*)node)->expanded;}void CallChain::select_node(void *node){}//////////////////////////////////////////////////////////////////////////////* * */void AnalyInfoline::init(Bounds *b, ht_aviewer *A, const char *Format){ ht_statictext::init(b, 0, align_left); VIEW_DEBUG_NAME("AnalyInfoline"); analy = A; displayformat = ht_strdup(Format); addr = new InvalidAddress(); fofs = INVALID_FILE_OFS;}void AnalyInfoline::done(){ free(displayformat); delete addr; ht_statictext::done();}int AnalyInfoline::gettext(char *buf, int maxlen){ if (maxlen <= 0) return 0; if (valid()) { const char *sec = analy->analy->getSegmentNameByAddress(addr); if (fofs != INVALID_FILE_OFS) { Location *a = analy->analy->getFunctionByAddress(addr); const char *func = analy->analy->getSymbolNameByLocation(a); char *d = displayformat; char *ss = buf, *s = buf; while (*d) { if (*d == '%') { d++; switch (*d) { case ANALY_STATUS_ARG_SECTION: if (sec) ss += ht_snprintf(ss, maxlen-(ss-s), "%s", sec); break; case ANALY_STATUS_ARG_FILEOFFSET: ss += ht_snprintf(ss, maxlen-(ss-s), "%08qx", fofs); break; case ANALY_STATUS_ARG_RAW_UNASM: { int length; ss += ht_snprintf(ss, maxlen-(ss-s), "%s", analy->analy->getDisasmStr(addr, length)); break; } case ANALY_STATUS_ARG_FUNCTION: { if (func) { int d = 0; addr->difference(d, a->addr); char sign = '+'; if (d < 0) { d =- d; sign = '-'; } ss += ht_snprintf(ss, maxlen-(ss-s), "%s%c%x", func, sign, d); } break; } case ANALY_STATUS_ARG_OFFSET: global_analyser_address_string_format = ADDRESS_STRING_FORMAT_LEADING_ZEROS; ss += ht_snprintf(ss, maxlen-(ss-s), "%y", addr); break; case '%': if (maxlen-(ss-s) > 1) { *ss++ = '%'; } break; default: ss += ht_snprintf(ss, maxlen-(ss-s), " error in format "); } } else { if (maxlen - (ss-s) > 1) { // leave space for trailing zero *ss++ = *d; } } d++; } *ss = 0; return ss - s; } else { if (!sec) { return ht_strlcpy(buf, "[not in file]", maxlen); } else { return ht_snprintf(buf, maxlen, "<%s> [not in file]", sec); } } } else { return ht_strlcpy(buf, "<no analyser>", maxlen); }}void AnalyInfoline::update(Address *cursor_addr, FileOfs ecursor_addr){ delete addr; if (valid()) { fofs = ecursor_addr; addr = cursor_addr->clone(); } else { fofs = INVALID_FILE_OFS; addr = new InvalidAddress(); } dirtyview(); redraw();}bool AnalyInfoline::valid(){ return ((analy)&&(analy->analy));}/* * */void ht_aviewer::init(Bounds *b, const char *desc, int caps, File *file, ht_format_group *format_group, Analyser *Analy){ analy = Analy; if (Analy) { analy->setDisplayMode(ANALY_SHOW_ADDRESS | ANALY_SHOW_COMMENTS | ANALY_SHOW_LABELS | ANALY_SHOW_XREFS | ANALY_TRANSLATE_SYMBOLS | ANALY_COLLAPSE_XREFS, ANALY_EDIT_BYTES); } analy_sub = NULL; ht_uformat_viewer::init(b, desc, caps, file, format_group); search_caps |= SEARCHMODE_BIN | SEARCHMODE_EVALSTR | SEARCHMODE_EXPR; infoline = NULL; idle_count = 0; last_active = true; pause = false; register_idle_object(this); one_load_hack = false;}void ht_aviewer::done(){ unregister_idle_object(this); ht_uformat_viewer::done(); if (analy) { analy->done(); // FIXME: this musnt be here delete analy; }}void ht_aviewer::attachInfoline(AnalyInfoline *V){ infoline = V;}bool ht_aviewer::pos_to_offset(viewer_pos p, FileOfs *ofs){ if (analy) { Address *addr; if (!convertViewerPosToAddress(p, &addr)) return false; FileOfs o=analy->addressToFileofs(addr); delete addr;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -