/* Disassemble the code segment, using the given decoder tables. * Note: The decoder tables specified in the flags argument will * be ignored. * * Parameters: * mbase - Memory region containing code segment. * vbase - PC address associated with first byte of memory region. * size - Number of bytes in memory region. * flags - Flags to use when decoding. */ static void NaClDisassembleSegmentUsingTables( uint8_t* mbase, NaClPcAddress vbase, NaClMemorySize size, NaClDisassembleFlags flags, const struct NaClDecodeTables* decoder_tables) { NaClSegment segment; NaClInstIter* iter; struct Gio* gout = NaClLogGetGio(); Bool print_internals = NaClHasBit(flags, NACL_DISASSEMBLE_FLAG(NaClDisassembleAddInternals)); NaClSegmentInitialize(mbase, vbase, size, &segment); iter = NaClInstIterCreate(decoder_tables, &segment); if (NULL == iter) { gprintf(gout, "Error: not enough memory\n"); } else { for (; NaClInstIterHasNext(iter); NaClInstIterAdvance(iter)) { NaClInstState* state = NaClInstIterGetState(iter); NaClInstStateInstPrint(gout, state); if (print_internals) { NaClInstPrintOpcodeSeq(gout, state); NaClInstPrint(gout, state->decoder_tables, NaClInstStateInst(state)); NaClExpVectorPrint(gout, state); } } NaClInstIterDestroy(iter); } }
void NaClInstStateInstPrint(struct Gio* file, NaClInstState* state) { int i; const NaClInst* inst; /* Print out the address and the inst bytes. */ int length = NaClInstStateLength(state); DEBUG_OR_ERASE( NaClInstPrint(file, state->decoder_tables, NaClInstStateInst(state))); DEBUG(NaClExpVectorPrint(file, state)); gprintf(file, "%"NACL_PRIxNaClPcAddressAll": ", NaClInstStatePrintableAddress(state)); for (i = 0; i < length; ++i) { gprintf(file, "%02"NACL_PRIx8" ", NaClInstStateByte(state, i)); } for (i = length; i < NACL_MAX_BYTES_PER_X86_INSTRUCTION; ++i) { gprintf(file, " "); } /* Print out the assembly instruction it disassembles to. */ inst = NaClInstStateInst(state); NaClPrintDisassembled(file, state, inst); gprintf(file, "\n"); }