void RiscOperators::dumpState() { Sawyer::Message::Stream out(thread_->tracing(TRACE_STATE)); out.enable(); out <<"Semantic state for thread " <<thread_->get_tid() <<":\n"; if (currentInstruction()) { out <<" instruction #" <<nInsns() <<" at " <<unparseInstructionWithAddress(currentInstruction()) <<"\n"; } else { out <<" processed " <<StringUtility::plural(nInsns(), "instructions") <<"\n"; } out <<" registers:\n"; BaseSemantics::Formatter format; format.set_line_prefix(" "); out <<(*currentState()->registerState()+format); out <<" memory:\n"; thread_->get_process()->mem_showmap(out, "memory:", " "); if (ARCH_X86 == architecture_) { out <<" segments:\n"; RegisterNames regNames(currentState()->registerState()->get_register_dictionary()); BOOST_FOREACH (const SegmentInfoMap::Node &node, segmentInfo_.nodes()) { RegisterDescriptor segreg(x86_regclass_segment, node.key(), 0, 16); out <<" " <<regNames(segreg) <<": base=" <<StringUtility::addrToString(node.value().base) <<" limit=" <<StringUtility::addrToString(node.value().limit) <<" present=" <<(node.value().present?"yes":"no") <<"\n"; } }
// Show the register state for BaseSemantics::RegisterStateGeneric in the same format as for RegisterStateX86. This is // for comparison of the two register states when verifying results. It's also close to the format used by the old binary // semantics API. void show_state(const BaseSemantics::RiscOperatorsPtr &ops) { #if SEMANTIC_DOMAIN == MULTI_DOMAIN std::cout <<*ops; return; #endif struct ShowReg { BaseSemantics::RiscOperatorsPtr ops; std::ostream &o; std::string prefix; ShowReg(const BaseSemantics::RiscOperatorsPtr &ops, std::ostream &o, const std::string &prefix) : ops(ops), o(o), prefix(prefix) {} void operator()(const char *name, const char *abbr=NULL) { const RegisterDictionary *regdict = ops->get_state()->get_register_state()->get_register_dictionary(); const RegisterDescriptor *desc = regdict->lookup(name); assert(desc); (*this)(*desc, abbr?abbr:name); } void operator()(const RegisterDescriptor &desc, const char *abbr) { BaseSemantics::RegisterStatePtr regstate = ops->get_state()->get_register_state(); FormatRestorer fmt(o); o <<prefix <<std::setw(8) <<std::left <<abbr <<"= { "; fmt.restore(); BaseSemantics::SValuePtr val = regstate->readRegister(desc, ops.get()); o <<*val <<" }\n"; } void operator()(unsigned majr, unsigned minr, unsigned offset, unsigned nbits, const char *abbr) { (*this)(RegisterDescriptor(majr, minr, offset, nbits), abbr); } } show(ops, std::cout, " "); std::cout <<"registers:\n"; show("eax", "ax"); show("ecx", "cx"); show("edx", "dx"); show("ebx", "bx"); show("esp", "sp"); show("ebp", "bp"); show("esi", "si"); show("edi", "di"); show("es"); show("cs"); show("ss"); show("ds"); show("fs"); show("gs"); show("cf"); show(x86_regclass_flags, 0, 1, 1, "?1"); show("pf"); show(x86_regclass_flags, 0, 3, 1, "?3"); show("af"); show(x86_regclass_flags, 0, 5, 1, "?5"); show("zf"); show("sf"); show("tf"); show("if"); show("df"); show("of"); show(x86_regclass_flags, 0, 12, 1, "iopl0"); show(x86_regclass_flags, 0, 13, 1, "iopl1"); show("nt"); show(x86_regclass_flags, 0, 15, 1, "?15"); show("rf"); show("vm"); show(x86_regclass_flags, 0, 18, 1, "ac"); show(x86_regclass_flags, 0, 19, 1, "vif"); show(x86_regclass_flags, 0, 20, 1, "vip"); show(x86_regclass_flags, 0, 21, 1, "id"); show(x86_regclass_flags, 0, 22, 1, "?22"); show(x86_regclass_flags, 0, 23, 1, "?23"); show(x86_regclass_flags, 0, 24, 1, "?24"); show(x86_regclass_flags, 0, 25, 1, "?25"); show(x86_regclass_flags, 0, 26, 1, "?26"); show(x86_regclass_flags, 0, 27, 1, "?27"); show(x86_regclass_flags, 0, 28, 1, "?28"); show(x86_regclass_flags, 0, 29, 1, "?29"); show(x86_regclass_flags, 0, 30, 1, "?30"); show(x86_regclass_flags, 0, 31, 1, "?31"); show("eip", "ip"); BaseSemantics::Formatter memfmt; memfmt.set_line_prefix(" "); std::cout <<"memory:\n"; ops->get_state()->print_memory(std::cout, memfmt); }