📄 out.cc
字号:
/* * HT Editor * out.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 "analy.h"#include "analy_names.h"#include "htdebug.h"#include "strtools.h"#include "snprintf.h"#include "tools.h"#include "out.h"// FIXME: grrrrrrrrrrr#include "x86dis.h"#include <string.h>#undef DPRINTF#define DPRINTF(msg...)#define DPRINTF2(msg...)//#define DPRINTF(msg...) printf(##msg)//#define DPRINTF2(msg...) printf(##msg)int compare_keys_addresses_delinear(Object *key_a, Object *key_b){ return ((Address*)key_a)->compareDelinear((Address*)key_b);}/* * */OutLine::OutLine(byte *Text, int Textlen, int Bytes){ textlen = Textlen; text = ht_malloc(Textlen); memcpy(text, Text, textlen); bytes = Bytes;}OutLine::~OutLine(){ free(text);}/* * */OutAddr::OutAddr(Address *aAddr, uint aTime){ addr = aAddr->clone(); updateTime(aTime); lines = new Array(true); size = 0; bytes = 0; }OutAddr::~OutAddr(){ delete addr; delete lines;}void OutAddr::appendLine(OutLine *l){ lines->insert(l); bytes += l->bytes; size += l->textlen;}void OutAddr::clear(){ lines->delAll(); bytes = 0; size = 0;}OutLine *OutAddr::getLine(int i){ return (OutLine*) (*lines)[i];}int OutAddr::compareTo(const Object *o) const{// uint oo = o->getObjectID(); return addr->compareTo(((OutAddr*)o)->addr);}void OutAddr::updateTime(uint Time){ time = Time;}/* * */void AnalyserOutput::init(Analyser *Analy){ analy = Analy; addr = new InvalidAddress(); cur_addr = NULL; cur_out_addr = NULL; out_addrs = new AVLTree(true); bytes_addr = 0; bytes_line = 0; size = 0; current_time = 0; work_buffer_start = ht_malloc(WORKBUF_LEN); work_buffer = work_buffer_start; work_buffer_end = work_buffer_start + WORKBUF_LEN - 1; *work_buffer_end = 0; temp_buffer = ht_malloc(WORKBUF_LEN); dis_style = DIS_STYLE_HIGHLIGHT+DIS_STYLE_HEX_NOZEROPAD+DIS_STYLE_HEX_ASMSTYLE+X86DIS_STYLE_OPTIMIZE_ADDR; changeConfig();}void AnalyserOutput::done(){ delete out_addrs; delete addr; free(work_buffer_start); free(temp_buffer);}void AnalyserOutput::beginAddr(){ bytes_addr = 0; line = 0;}void AnalyserOutput::beginLine(){ work_buffer = work_buffer_start; bytes_line = 0;}void AnalyserOutput::changeConfig(){}int AnalyserOutput::elementLength(const char *s){ return strlen(s);}void AnalyserOutput::endAddr(){}void AnalyserOutput::endLine(){ cur_out_addr->appendLine(new OutLine(work_buffer_start, (work_buffer-work_buffer_start), bytes_line)); bytes_addr += bytes_line; line++;}void AnalyserOutput::footer(){ // STUB}static char *analyser_output_addr_sym_func(CPU_ADDR Addr, int *symstrlen, void *context){ AnalyserOutput *output = (AnalyserOutput *) context; char *buf; Address *addr = output->analy->createAddress();/* if (Addr.addr32.offset == 0xaea) { int as=0; }*/ addr->getFromCPUAddress(&Addr); Location *loc = output->analy->getLocationByAddress(addr); if (loc && loc->label) { buf = output->link(loc->label->name, addr); if (symstrlen) *symstrlen = output->elementLength(buf); delete addr; return buf; } else { if (output->analy->validAddress(addr, scvalid)) { char m[90]; addr->stringify(m, sizeof m, ADDRESS_STRING_FORMAT_COMPACT | ADDRESS_STRING_FORMAT_ADD_H); buf = output->link(m, addr); if (symstrlen) *symstrlen = output->elementLength(buf); delete addr; return buf; } } delete addr; return NULL;}void AnalyserOutput::generateAddr(Address *Addr, OutAddr *oa){#define LABELINDENT 32#define MAX_XREF_COLS 3#define MAX_XREF_LINES 7#if 0 char tbuf[1024]; Addr->stringify(tbuf, sizeof tbuf, 0); printf("generate_addr(%s, ", tbuf); char tbuf2[1024]; addr->stringify(tbuf2, sizeof tbuf2, 0); printf("%s)\n", tbuf2);#endif cur_addr = analy->getLocationByAddress(addr); cur_out_addr = oa; cur_out_addr->clear(); beginAddr(); if (cur_addr) { int xref_count = cur_addr->xrefs ? cur_addr->xrefs->count() : 0; // comments CommentList *c = cur_addr->comments; if (c && (analy->mode & ANALY_SHOW_COMMENTS)) { int c1 = c->count(); for (int i=0; i < c1; i++) { beginLine(); putElement(ELEMENT_TYPE_PRE_COMMENT, c->getName(i)); endLine(); } } // label && xrefs bool collapsed_xrefs = false; if (analy->mode & ANALY_COLLAPSE_XREFS) { // count xrefs if (xref_count >= MAX_XREF_COLS * MAX_XREF_LINES) { collapsed_xrefs = true; } } if ((cur_addr->label && (analy->mode & ANALY_SHOW_LABELS)) || (cur_addr->xrefs && (analy->mode & ANALY_SHOW_XREFS))) { beginLine(); // label int labellength = (cur_addr->label) ? strlen(cur_addr->label->name) : 0; if (labellength && (analy->mode & ANALY_SHOW_LABELS)) { putElement(ELEMENT_TYPE_LABEL, cur_addr->label->name); write(":"); labellength++; } // xrefs if (labellength >= LABELINDENT && cur_addr->xrefs) { endLine(); beginLine(); labellength = 0; } if (collapsed_xrefs) { for (int j=labellength; j<LABELINDENT; j++) write(" "); char b[32]; sprintf(b, "<< show xrefs (%d) >>", xref_count); char *t; uint64 u; Addr->putIntoUInt64(u); t = externalLink(b, u >> 32, u, 0, 1, NULL); write(t); } else { Container *xr = cur_addr->xrefs; if (xr) { int i=0; ObjHandle xh = xr->findFirst(); while (xh != invObjHandle) { if ((i % (MAX_XREF_COLS+1))!=0) { AddrXRef *x = (AddrXRef *)xr->get(xh); char buf3[90]; sprintf(buf3, " %c", xref_type_short(x->type)); write(buf3); x->addr->stringify(buf3, 1024, ADDRESS_STRING_FORMAT_COMPACT); write(link(buf3, x->addr)); xh = xr->findNext(xh); } else { if (i!=0) { endLine(); beginLine(); } for (int j=labellength; j<LABELINDENT; j++) write(" "); labellength = 0; putElement(ELEMENT_TYPE_COMMENT, ";xref"); } i++; } } } endLine(); } } beginLine(); bool is_valid_ini_addr = analy->validAddress(addr, scinitialized); bool is_valid_code_addr = analy->validCodeAddress(addr); if ( is_valid_ini_addr && ( ( cur_addr && ( cur_addr->type.type == dt_code || ( cur_addr->type.type == dt_unknown && is_valid_code_addr ) ) ) || ( !cur_addr && is_valid_code_addr ) ) ) { // code Location *next_addr = analy->enumLocations(addr); int op_len; // max. length of current opcode if (next_addr) { int d = 255; next_addr->addr->difference(d, addr); op_len = MIN(uint32(analy->max_opcode_length), uint(d)); } else { op_len = analy->max_opcode_length; } byte buf[16]; int buffer_size = analy->bufPtr(addr, buf, sizeof buf); if (analy->disasm && buffer_size) { OPCODE *o = analy->disasm->decode(buf, MIN(buffer_size, op_len), analy->mapAddr(Addr)); /* inits for addr-sym transformations */ addr_sym_func_context = this; if (analy->mode & ANALY_TRANSLATE_SYMBOLS) addr_sym_func = &analyser_output_addr_sym_func; int complete_bytes_line = analy->disasm->getSize(o); bool s = true; do { if (s) { const char *x = analy->disasm->str(o, dis_style); putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, x); } if ((s = analy->disasm->selectNext(o))/* || complete_bytes_line*/) { endLine(); beginLine(); } else { if (analy->mode & ANALY_EDIT_BYTES) { want_bytes_line = MIN(complete_bytes_line, 16); } else { want_bytes_line = complete_bytes_line; } bytes_line += want_bytes_line; complete_bytes_line -= want_bytes_line; } } while (s || complete_bytes_line); /* deinits for addr-sym transformations */ addr_sym_func_context = NULL; addr_sym_func = NULL; } else { if (buffer_size >= 1) { char buff[20]; sprintf(buff, "db \\@n%02xh", buf[0]); putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, buff); sprintf(buff, " ; '%c'", (buf[0]<32)?' ':buf[0]); putElement(ELEMENT_TYPE_COMMENT, buff); } else { putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, "db ??"); } bytes_line = want_bytes_line = 1; } } else { // data if (analy->validAddress(addr, scvalid)) { if (cur_addr && (cur_addr->type.type != dt_unknown) && (cur_addr->type.type != dt_unknown_data) && (cur_addr->type.type != dt_code)) { switch (cur_addr->type.type) { case dt_int: { bytes_line = want_bytes_line = cur_addr->type.length; assert(cur_addr->type.length); if (analy->validAddress(addr, scinitialized)) { char buf[50]; switch (cur_addr->type.int_subtype) { case dst_iword: { uint16 c; analy->bufPtr(addr, (byte *)&c, 2); sprintf(buf, "dw \\@n%04xh", c); putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, buf); break; } case dst_idword: { uint32 c; analy->bufPtr(addr, (byte *)&c, 4); sprintf(buf, "dd \\@n%08xh", c); putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, buf); break; } case dst_iqword: { uint64 c; analy->bufPtr(addr, (byte *)&c, 8); ht_snprintf(buf, sizeof buf, "dq \\@n%016qxh", c); putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, buf); break; } case dst_ibyte: default: { byte c; if (analy->bufPtr(addr, &c, 1)==1) { sprintf(buf, "db \\@n%02xh ", c); putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, buf); sprintf(buf, "; '%c'", (c<32)?32:c); putElement(ELEMENT_TYPE_COMMENT, buf); } else { putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, "db ??"); } } } } else { // not initialized switch (cur_addr->type.int_subtype) { case dst_iword: putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, "dw ????"); break; case dst_idword: putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, "dd ????????"); break; case dst_iqword: putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, "dq ????????????????"); break; case dst_ibyte:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -