📄 analy.cc
字号:
}/* * */static Symbol *analyserfindlabel(Symbol *labels, const char *label){ if (labels) { int i = strcmp(label, labels->name); if (i < 0) return analyserfindlabel(labels->left, label); if (i > 0) return analyserfindlabel(labels->right, label); return labels->location ? labels : NULL; } return NULL;}/* * */Symbol *Analyser::getSymbolByName(const char *label){ return analyserfindlabel(symbols, label);}const char *Analyser::getSymbolNameByLocation(Location *loc){ return loc ? (loc->label ? loc->label->name : NULL): NULL;}/** * converts |FileOfs fileofs| to |Address| */Address *Analyser::fileofsToAddress(FileOfs fileaddr){ // abstract / stub return new InvalidAddress();}/** * called once every time the analyser has nothing more to do. */void Analyser::finish(){ DPRINTF("the analyser finished (for now).\n"); cur_func = NULL; delete addr; addr = new InvalidAddress(); setActive(false);}/* * */void Analyser::freeLocation(Location *loc){ if (loc) { // label will be freed separatly delete loc->xrefs; freeComments(loc); delete loc->addr; delete loc; }}/* * */void Analyser::freeLocations(Location *addrs){ if (addrs) { freeLocations(addrs->left); freeLocations(addrs->right); freeLocation(addrs); }}/* * */void Analyser::freeComments(Location *aAddr){ delete aAddr->comments; aAddr->comments = NULL;}/* * */void Analyser::freeSymbol(Symbol *label){ if (label) { free(label->name); delete label; }}/* * */void Analyser::freeSymbols(Symbol *labels){ if (labels) { freeSymbols(labels->left); freeSymbols(labels->right); freeSymbol(labels); }}/* * */CommentList *Analyser::getComments(Address *Addr){ Location *a = getLocationByAddress(Addr); if (a) { return a->comments; } return NULL;}static char *analy_addr_sym_func2(CPU_ADDR Addr, int *symstrlen, void *analy){ Address *a = ((Analyser*)analy)->createAddress(); a->getFromCPUAddress(&Addr); Location *loc = ((Analyser*)analy)->getLocationByAddress(a); delete a; if (loc && loc->label) { if (symstrlen) *symstrlen = strlen(loc->label->name); return loc->label->name; } return NULL;}/* * */const char *Analyser::getDisasmStr(Address *Addr, int &length){ if (validAddress(Addr, scinitialized)) { if (disasm) { addr_sym_func = NULL; byte buf[16]; int bz = bufPtr(Addr, buf, sizeof(buf)); OPCODE *o = disasm->decode(buf, MIN(bz, max_opcode_length), mapAddr(Addr)); length = disasm->getSize(o); return disasm->strf(o, DIS_STYLE_HEX_NOZEROPAD+DIS_STYLE_HEX_ASMSTYLE, DISASM_STRF_SMALL_FORMAT); } else { return "<no disassembler!>"; } } else { return ""; }}/* * */const char *Analyser::getDisasmStrFormatted(Address *Addr){ if (disasm) { addr_sym_func_context = this; addr_sym_func = &analy_addr_sym_func2; byte buf[16]; int bz = bufPtr(Addr, buf, sizeof(buf)); OPCODE *o=disasm->decode(buf, MIN(bz, max_opcode_length), mapAddr(Addr)); const char *res = disasm->strf(o, DIS_STYLE_HEX_NOZEROPAD+DIS_STYLE_HEX_ASMSTYLE, DISASM_STRF_SMALL_FORMAT); addr_sym_func_context = NULL; addr_sym_func = NULL; return res; } else { return "<no disassembler!>"; }}/* * */int Analyser::getDisplayMode(){ return mode;}static void analysergetlocationcount(Location *addr, int *c){ if (addr) { analysergetlocationcount(addr->left, c); if (!(addr->flags & AF_DELETED)) (*c)++; analysergetlocationcount(addr->right, c); }}/* * */int Analyser::getLocationCount() const{ int c=0; analysergetlocationcount(locations, &c); return c;}/* * */String & Analyser::getName(String &res){ return res = "generic";}static void analysergetsymbolcount(Symbol *l, int *c){ if (l) { analysergetsymbolcount(l->left, c); if (l->location) (*c)++; analysergetsymbolcount(l->right, c); }}/* * */int Analyser::getSymbolCount() const{ int c=0; analysergetsymbolcount(symbols, &c); return c;}/* * */const char *Analyser::getSegmentNameByAddress(Address *Addr){ return NULL;}/* * */Symbol *Analyser::getSymbolByAddress(Address *Addr){ Location *a = getLocationByAddress(Addr); return (a) ? a->label : NULL;}/* * */const char *Analyser::getType(){ return "generic";}/* * */Container *Analyser::getXRefs(Address *Addr){ Location *a = getLocationByAddress(Addr); if (!a) return NULL; return a->xrefs;}/* * */bool Analyser::gotoAddress(Address *aAddr, Address *func){ DPRINTF("goto(%y, %y)\n", aAddr, func); int diff; if (first_explored->difference(diff, last_explored) && diff < 0) { DPRINTF("explored->add(%y - %y)\n", first_explored, last_explored); explored->add(first_explored, last_explored); } delete first_explored; delete last_explored; delete next_explored; func = func->clone(); if (!validCodeAddress(aAddr) || explored->contains(aAddr)) { DPRINTF("Address: %y Valid: %d Explored: %d\n", addr, validCodeAddress(addr), explored->contains(addr)); do { delete addr; delete func; if (!popAddress(&addr, &func)) { first_explored = new InvalidAddress(); last_explored = new InvalidAddress(); next_explored = new InvalidAddress(); addr = new InvalidAddress(); return false; } DPRINTF("pop %y (Valid: %d Explored: %d)\n", addr, validCodeAddress(addr), explored->contains(addr)); } while ((explored->contains(addr)) || (!validCodeAddress(addr))); } else { if (addr != aAddr) { delete addr; addr = aAddr->clone(); } } if (func->isValid()) { cur_func = newLocation(func); setLocationFunction(cur_func, cur_func); } delete func; next_explored = (Address *)explored->findNext(addr); if (!next_explored) { next_explored = new InvalidAddress(); } else { next_explored = next_explored->clone(); } first_explored = addr->clone(); last_explored = addr->clone(); return true;}/* * */void Analyser::initCodeAnalyser(){ code = new CodeAnalyser(); code->init(this);}/* * */void Analyser::initDataAnalyser(){ data = new DataAnalyser(); data->init(this);}/* * */bool Analyser::isDirty(){ return dirty;}/* * */void Analyser::log(const char *s){ // stub}/* * */void Analyser::makeDirty(){ dirty = true;}/* * */CPU_ADDR Analyser::mapAddr(Address *aAddr){ /* * this function should map the independent address Addr to a * processor dependent * e.g. .23423 --> 00234324 (or something like this) * it is only used for relativ calls/jumps */ CPU_ADDR a; aAddr->putIntoCPUAddress(&a); return a;}Location *Analyser::newLocation(Location *&locs, Address *aAddr){ if (locs) { if (aAddr->compareTo(locs->addr) < 0) return newLocation(locs->left, aAddr); if (aAddr->compareTo(locs->addr) > 0) return newLocation(locs->right, aAddr); } else { locs = new Location; memset(locs, 0, sizeof *locs); locs->addr = aAddr->clone(); location_count++; } locs->flags &= ~AF_DELETED; return locs;}/* * */Location *Analyser::newLocation(Address *Addr){/* if (!(cur_addr_ops--)) { optimizeLocationTree(); }*/ return newLocation(locations, Addr);}Symbol *Analyser::newSymbol(Symbol *&labels, const char *label, Location *loc, labeltype type){ if (labels) { int i = strcmp(label, labels->name); if (i < 0) return newSymbol(labels->left, label, loc, type); if (i > 0) return newSymbol(labels->right, label, loc, type); if (!labels->location) { labels->location = loc; if (type != label_unknown) labels->type = type; } } else { labels = new Symbol; labels->name = ht_strdup(label); labels->location = loc; labels->type = type; labels->left = NULL; labels->right = NULL; symbol_count++; } return labels;}/* * */Symbol *Analyser::newSymbol(const char *label, Location *loc, labeltype type, Location *infunc){/* if (!(cur_label_ops--)) { optimizeSymbolTree(); }*/ Symbol *result = newSymbol(symbols, label, loc, type); if ((result) && (result->location==loc) && (infunc)) setLocationFunction(loc, infunc); return result;}/* * optimizes(=balances) addr tree */void Analyser::optimizeLocationTree(){ cur_addr_ops = location_threshold; // implement me!}/* * see optimize_addr_tree() */void Analyser::optimizeSymbolTree(){ cur_label_ops = symbol_threshold; // implement me!}/* * */bool Analyser::popAddress(Address **Addr, Address **func){ if (!addr_queue->isEmpty()) { AddressQueueItem *aqi = (AddressQueueItem *) addr_queue->deQueue(); *Addr = aqi->addr->clone(); *func = aqi->func->clone(); delete aqi; DPRINTF("addr %y (from sub %y) poped\n", *Addr, *func); return true; } else { DPRINTF("pop failed -> analyser obviously finished\n"); return false; }}/* * */void Analyser::pushAddress(Address *Addr, Address *func){ if (validCodeAddress(Addr)) { if (!func->isValid()) { if (cur_func) { func = cur_func->addr; } } DPRINTF("addr %y (from func %y) pushed\n", Addr, func); AddressQueueItem *aqi = new AddressQueueItem(Addr, func); addr_queue->enQueue(aqi); }}/* * */int Analyser::queryConfig(int mode){ switch (mode) { case Q_DO_ANALYSIS: case Q_ENGAGE_CODE_ANALYSER: case Q_ENGAGE_DATA_ANALYSER: return true; default: return 0; }}static void saveaddrs(ObjectStream &st, Location *addr){ if (addr) { saveaddrs(st, addr->left); if (!(addr->flags & AF_DELETED)) { PUTX_OBJECT(st, addr->addr, "addr"); PUTX_OBJECT(st, addr->xrefs, "xrefs"); PUTX_OBJECT(st, addr->comments, "comments"); analyser_put_addrtype(st, &addr->type); if (addr->thisfunc) { PUTX_OBJECT(st, addr->thisfunc->addr, "func"); } else { Address *invalid_addr = new InvalidAddress(); PUTX_OBJECT(st, invalid_addr, "func"); delete invalid_addr; } PUTX_INT8X(st, addr->flags, "flags"); } saveaddrs(st, addr->right); }}static void savelabels(ObjectStream &st, Symbol *label){ if (label) { savelabels(st, label->left); if (label->location) { // label isn't deleted PUTX_OBJECT(st, label->location->addr, "addr"); PUTX_STRING(st, label->name, "name"); int a = (int)label->type; PUTX_INTX(st, a, 1, "type"); } savelabels(st, label->right); }}/* * */void Analyser::store(ObjectStream &st) const{ PUT_OBJECT(st, addr); PUT_OBJECT(st, addr_queue); PUT_INT32D(st, ops_parsed); PUT_BOOL(st, active); PUT_OBJECT(st, next_explored); PUT_OBJECT(st, first_explored); PUT_OBJECT(st, last_explored); PUT_INT32X(st, mode); PUT_OBJECT(st, explored); PUT_OBJECT(st, initialized); st.putComment("locations"); PUTX_INT32D(st, getLocationCount(), "location_count"); saveaddrs(st, locations); st.putComment("symbols"); PUTX_INT32D(st, getSymbolCount(), "symbol_count"); savelabels(st, symbols); PUT_OBJECT(st, analy_disasm); PUT_OBJECT(st, disasm); PUT_OBJECT(st, code); PUT_OBJECT(st, data); PUT_INT32D(st, location_threshold); PUT_INT32D(st, symbol_threshold); PUT_INT32D(st, max_opcode_length); if (cur_func) { PUTX_OBJECT(st, cur_func->addr, "cur_func"); } else { PUTX_OBJECT(st, NULL, "cur_func"); } dirty = false;}/* * */void Analyser::setActive(bool mode){ if (mode) { if (!active) { active = true; some_analyser_active++; } } else { if (active) { active = false; some_analyser_active--; } }}/* * */void Analyser::setDisplayMode(int enable, int disable){ mode &= ~disable; mode |= enable;}/* * */void Analyser::setLocationFunction(Location *a, Location *func){ if (a) { a->thisfunc = func; a->flags &= !AF_FUNCTION_END; a->flags |= AF_FUNCTION_SET; }}/* * */void Analyser::setDisasm(Disassembler *d){ disasm = d; if (disasm) { int t; disasm->getOpcodeMetrics(t, max_opcode_length, t, t, t); } else { max_opcode_length = 1; }}/* * sets addr_threshold. after threshold addr_tree ops the tree will * be optimized */void Analyser::setLocationTreeOptimizeThreshold(int threshold){ location_threshold = threshold; if (cur_addr_ops > location_threshold) cur_addr_ops = location_threshold;}/* * see set_addr_tree_optimize_threshold */void Analyser::setSymbolTreeOptimizeThreshold(int threshold){ symbol_threshold = threshold; if (cur_label_ops > symbol_threshold) cur_label_ops = symbol_threshold;}/* * */void Analyser::toggleDisplayMode(int toggle){ mode ^= toggle;}/* * */bool Analyser::validCodeAddress(Address *Addr){ Location *a = getLocationByAddress(Addr); if (a) { if ((a->type.type != dt_code) && (a->type.type != dt_unknown)) return false; } return validAddress(Addr, sccode);}/* * */bool Analyser::validReadAddress(Address *Addr){ return validAddress(Addr, scread);}/* * */bool Analyser::validWriteAddress(Address *Addr){ return validAddress(Addr, scwrite);}/****************************************************************************/AnalyDisassembler::AnalyDisassembler(){ disasm = NULL;}/* * */void AnalyDisassembler::init(Analyser *A){ analy = A; initDisasm();}/* * */void AnalyDisassembler::initDisasm(){ if (analy) { analy->setDisasm(disasm); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -