TCA UniqueStubs::add(const char* name, TCA start) { auto const inAStubs = start > mcg->code.stubs().base(); UNUSED auto const stop = inAStubs ? mcg->code.stubs().frontier() : mcg->code.main().frontier(); FTRACE(1, "unique stub: {} {} -- {:4} bytes: {}\n", inAStubs ? "astubs @ " : " ahot @ ", static_cast<void*>(start), static_cast<size_t>(stop - start), name); ONTRACE(2, [&]{ Disasm dasm(Disasm::Options().indent(4)); std::ostringstream os; dasm.disasm(os, start, stop); FTRACE(2, "{}\n", os.str()); }() ); mcg->recordGdbStub( mcg->code.blockFor(start), start, strdup(folly::format("HHVM::{}", name).str().c_str()) ); return start; }
void DisasmViewer::memoryUpdated(CommMemoryRequest* req) { // disassemble the newly received memory dasm(memory, req->offset, req->offset + req->size - 1, disasmLines, memLayout, symTable, programAddr); // locate the requested line disasmTopLine = findDisasmLine(req->address, req->line); switch (req->method) { case Middle: case MiddleAlways: disasmTopLine -= visibleLines / 2; break; case Bottom: case BottomAlways: disasmTopLine -= visibleLines - 1; break; } disasmTopLine = std::max(disasmTopLine, 0); disasmTopLine = std::min(disasmTopLine, int(disasmLines.size()) - visibleLines); updateCancelled(req); // sync the scrollbar with the actual address reached if (!waitingForData) { // set the slider with without the signal disconnect(scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarChanged(int))); scrollBar->setSliderPosition(disasmLines[disasmTopLine].addr); connect (scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarChanged(int))); // set the line setAddress(disasmLines[disasmTopLine].addr, disasmLines[disasmTopLine].infoLine); update(); }
/* * m a i n * * Main routine of dis_o386. */ int main(int argc, char *argv[]) { char *cp, objfile[BUFF_LEN], symbfile[BUFF_LEN]; char table[MAXSECT*(SZ_NAME+2)]; int j, errors; unsigned long int addrfirst, addrlast, addrcount; struct stat statbuff; /* initial set up */ if ((cp = strrchr(argv[0], PSEP)) == (char *)NULL) cp = argv[0]; else cp++; strncpy(progname, cp, BUFF_MAX); strncpy(objfile, OBJF, BUFF_MAX); addrfirst = addrlast = addrcount = 0; /* clear the in-core name tables */ o_strtab = (char *)NULL; for (j = 0 ; j < MAXSECT ; j++) o_secnam[j] = table + j * (SZ_NAME + 2); /* nb. leading '_' */ for (j = 0 ; j < sizeof(table) ; j++) table[j] = '\0'; /* check for an MSDOS-style option */ if (argc == 2 && argv[1][0] == '/') { usage(); exit(0); } /* parse arguments */ errors = opterr = 0; while ((j = getopt(argc, argv, "O:S:abdf:hl:mnrstx:")) != EOF) { switch (j & 0177) { #if 0 case 'C': /* core file name */ opt_C = TRUE; if (optarg != (char *)NULL) strncpy(binfile, optarg, BUFF_MAX); else errors++; break; case 'E': /* executable file name */ opt_E = TRUE; if (optarg != (char *)NULL) strncpy(binfile, optarg, BUFF_MAX); else errors++; break; #endif case 'O': /* object file name */ opt_O = TRUE; if (optarg != (char *)NULL) strncpy(objfile, optarg, BUFF_MAX); else errors++; break; case 'S': /* symbol table name */ opt_S = TRUE; if (optarg != (char *)NULL) strncpy(symbfile, optarg, BUFF_MAX); else errors++; break; case 'a': /* dump tables and disassemble segments */ opt_a = TRUE; break; case 'b': /* dump straight binary */ opt_b = TRUE; break; case 'd': /* dump the data segment */ opt_d = TRUE; break; case 'f': /* first address of dump */ opt_f = TRUE; if (optarg != (char *)NULL) { addrfirst = atoaddr(optarg); } else errors++; break; case 'h': /* dump the header */ opt_h = TRUE; break; case 'l': /* last address of dump */ opt_l = TRUE; if (optarg != (char *)NULL) { addrlast = atoaddr(optarg); } else errors++; break; case 'm': /* dump the rom segment */ opt_m = TRUE; break; case 'n': /* dump the symbol names */ opt_n = TRUE; break; case 'r': /* dump the relocation structures */ opt_r = TRUE; break; case 's': /* dump the symbol table */ opt_s = TRUE; break; case 't': /* dump the text segment */ opt_t = TRUE; break; #if 0 case 'u': /* dump the bss segment */ opt_u = TRUE; break; #endif case 'x': /* debugging flag */ opt_x = TRUE; if (optarg != (char *)NULL) dbglvl = atoi(optarg); break; case '?': default: usage(); exit(1); break; } } /* check the flags */ if (errors > 0) { usage(); exit(1); } if (opt_a && (opt_d || opt_h || opt_m || opt_n || opt_r || opt_s || opt_t)) { usage(); exit(1); } if ((opt_f || opt_l) && (addrlast > 0 && addrfirst > addrlast)) { usage(); exit(1); } /* check for a specific input file */ if (optind < argc) strncpy(objfile, argv[optind], BUFF_MAX); /* we must have a binary file of some sort */ if ((objfp = fopen(objfile, "rb")) == (FILE *)NULL || stat(objfile, &statbuff) == -1) { perror(objfile); exit(1); } /* initialise the object file data structures */ if (init_objf(objfp) == FAILED) { perror(objfile); exit(1); } /* show the output file name and date */ fprintf(stdout, "File name: %s\nFile date: %s", objfile, ctime(&statbuff.st_ctime)); /* show the header and section data - default behaviour */ if (opt_a || opt_h || (!opt_d && !opt_m && !opt_n && !opt_r && !opt_s && !opt_t)) { fprintf(stdout, "\nHeader data:\n"); (void) dump_ohdr(&o_hdrbuf); fprintf(stdout, "\nSection data:\n"); (void) fseek(objfp, OFF_SECT(hdrbuf), SEEK_SET); (void) dump_oshdr(objfp, 0, o_hdrbuf.oh_nsect); } /* The core start address is zero for every section. What allowances * should be made for the differences between file and core images? */ /* dump or disassemble the rom section */ if (opt_a || opt_m) { if (opt_b) (void) dump_osec(addrfirst, addrlast, ROM, FALSE); else (void) dump_osec(addrfirst, addrlast, ROM, TRUE); } /* dump or disassemble the data section */ if (opt_a || opt_d) { if (opt_b) (void) dump_osec(addrfirst, addrlast, DATA, FALSE); else (void) dump_osec(addrfirst, addrlast, DATA, TRUE); } /* dump or disassemble the text section */ if (opt_a || opt_t) { /* check that all offsets are valid */ if (addrfirst > o_sectab[TEXT].os_flen || addrlast > o_sectab[TEXT].os_flen) { fprintf(stderr, "Invalid %s address range 0x%08.8lu to 0x%08.8lu\n", "text", addrfirst, addrlast); } else { if (opt_b) (void) dump_osec(addrfirst, addrlast, TEXT, FALSE); else { addrcount = (addrlast == 0) ? o_sectab[TEXT].os_flen : addrlast; addrcount -= addrfirst; disfp = objfp; /* file to be disassembled */ (void) fseek(disfp, o_sectab[TEXT].os_foff + addrfirst, SEEK_SET); fprintf(stdout, "\nDisassembled text:\n"); (void) dasm(addrfirst, addrcount); } } } /* show the relocation data */ if (opt_a || opt_r) { if (opt_b) addrcount = o_hdrbuf.oh_nrelo * sizeof(struct outrelo); else addrcount = o_hdrbuf.oh_nrelo; /* check that all offsets are valid */ if (addrfirst >= addrcount || addrlast >= addrcount) { fprintf(stderr, "Invalid %s address range 0x%08.8lu to 0x%08.8lu\n", "relocation", addrfirst, addrlast); } else { if (opt_l) addrcount = addrlast + 1; addrcount = addrcount - addrfirst; if (opt_b) { fprintf(stdout, "\nRelocation data dump:\n"); (void) fseek(objfp, OFF_RELO(o_hdrbuf) + addrfirst, SEEK_SET); (void) dump_hex(objfp, addrfirst, addrcount); } else { fprintf(stdout, "\nRelocation data:\n"); (void) fseek(objfp, OFF_RELO(o_hdrbuf) + addrfirst * sizeof(struct outrelo), SEEK_SET); (void) dump_orel(objfp, addrfirst, addrcount); } } } /* show the symbol data */ if (opt_a || opt_s) { if (opt_b) addrcount = o_hdrbuf.oh_nname * sizeof(struct outname); else addrcount = o_hdrbuf.oh_nname; /* check that all offsets are valid */ if (addrfirst >= addrcount || addrlast >= addrcount) { fprintf(stderr, "Invalid %s address range 0x%08.8lu to 0x%08.8lu\n", "symbol", addrfirst, addrlast); } else { if (opt_l) addrcount = addrlast + 1; addrcount = addrcount - addrfirst; if (opt_b) { fprintf(stdout, "\nSymbol data dump:\n"); (void) fseek(objfp, OFF_NAME(o_hdrbuf) + addrfirst, SEEK_SET); (void) dump_hex(objfp, addrfirst, addrcount); } else { fprintf(stdout, "\nSymbol data:\n"); (void) fseek(objfp, OFF_NAME(o_hdrbuf) + addrfirst * sizeof(struct outname), SEEK_SET); (void) dump_osym(objfp, addrfirst, addrcount); } } } /* show the string data */ if (opt_a || opt_n) { if (opt_b) addrcount = o_hdrbuf.oh_nchar; else addrcount = o_hdrbuf.oh_nname; /* assumes one name per symbol */ /* check that all offsets are valid */ if (addrfirst >= addrcount || addrlast >= addrcount) { fprintf(stderr, "Invalid %s address range 0x%08.8lu to 0x%08.8lu\n", "symbol", addrfirst, addrlast); } else { if (opt_l) addrcount = addrlast + 1; addrcount = addrcount - addrfirst; if (opt_b) { fprintf(stdout, "\nName data dump:\n"); (void) fseek(objfp, OFF_CHAR(o_hdrbuf) + addrfirst, SEEK_SET); (void) dump_hex(objfp, addrfirst, addrcount); } else { fprintf(stdout, "\nName data:\n"); (void) fseek(objfp, o_symtab[addrfirst].on_foff, SEEK_SET); (void) dump_ostr(objfp, addrfirst, addrcount); } } } /* wrap up */ fclose(objfp); exit(0); }