void DisassemblerContext::print_function_type_term(const ValuePtr<FunctionType>& term, bool bracket, const ValuePtr<Function>& use_names) { PSI_ASSERT(!use_names || (term->parameter_types().size() == use_names->parameters().size())); if (bracket) *m_output << '('; *m_output << "function"; switch (term->calling_convention()) { case cconv_c: break; case cconv_x86_stdcall: *m_output << " cc_x86_stdcall"; case cconv_x86_thiscall: *m_output << " cc_x86_thiscall"; case cconv_x86_fastcall: *m_output << " cc_x86_fastcall"; default: PSI_FAIL("Unknown calling convention in disassembler"); } if (term->sret()) *m_output << " sret"; *m_output << " ("; unsigned n_parameters = term->parameter_types().size(); unsigned parameter_name_base = m_parameter_name_index; m_parameter_name_index += n_parameters; boost::format name_formatter("%%%s"); m_parameter_names.push_back(ParameterNameList::value_type()); ParameterNameList::value_type& name_list = m_parameter_names.back(); for (unsigned ii = 0; ii != n_parameters; ++ii) { if (ii) *m_output << ", "; std::string name; if (use_names) { *m_output << TermNamePrinter(&m_names.find(use_names->parameters().at(ii))->second->name); } else { *m_output << name_formatter % (parameter_name_base + ii); } const ParameterType& ty = term->parameter_types()[ii]; *m_output << " :"; print_parameter_attributes(ty.attributes); *m_output << ' '; print_term(ty.value, false); name_list.push_back(name); } *m_output << ") >"; print_parameter_attributes(term->result_type().attributes); *m_output << ' '; print_term(term->result_type().value, true); m_parameter_names.pop_back(); m_parameter_name_index = parameter_name_base; if (bracket) *m_output << ')'; }
void DisassemblerContext::setup_term(const ValuePtr<>& term) { if (!m_visited_terms.insert(term).second) return; setup_term_name(term); switch (term->term_type()) { case term_apply: { ValuePtr<ApplyType> apply = value_cast<ApplyType>(term); setup_term(apply->recursive()); for (std::vector<ValuePtr<> >::const_iterator ii = apply->parameters().begin(), ie = apply->parameters().end(); ii != ie; ++ii) setup_term(*ii); break; } case term_exists: { ValuePtr<Exists> exists = value_cast<Exists>(term); setup_term(exists->result()); break; } case term_parameter_placeholder: case term_recursive_parameter: { setup_term(term->type()); break; } case term_functional: { class MyVisitor : public FunctionalValueVisitor { DisassemblerContext *m_self; public: MyVisitor(DisassemblerContext *self) : m_self(self) {} virtual void next(const ValuePtr<>& v) {if (v) m_self->setup_term(v);} }; MyVisitor my_visitor(this); value_cast<FunctionalValue>(term)->functional_visit(my_visitor); break; } case term_function_type: { ValuePtr<FunctionType> cast_term = value_cast<FunctionType>(term); const std::vector<ParameterType>& parameter_types = cast_term->parameter_types(); for (std::vector<ParameterType>::const_iterator ii = parameter_types.begin(), ie = parameter_types.end(); ii != ie; ++ii) setup_term(ii->value); setup_term(cast_term->result_type().value); break; } default: return; // Skip adding to definition list } if (TermDefinitionList *dl = term_definition_list(term)) dl->push_back(term); }
void DisassemblerContext::print_apply_term(const ValuePtr<ApplyType>& apply, bool bracket) { if (bracket) *m_output << '('; *m_output << "apply "; print_term(apply->recursive(), true); for (std::vector<ValuePtr<> >::const_iterator ii = apply->parameters().begin(), ie = apply->parameters().end(); ii != ie; ++ii) { *m_output << ' '; print_term(*ii, true); } if (bracket) *m_output << ')'; }
void DisassemblerContext::print_recursive(const ValuePtr<RecursiveType>& term) { *m_output << "recursive ("; boost::format name_formatter("%%%s"); for (RecursiveType::ParameterList::const_iterator ib = term->parameters().begin(), ii = term->parameters().begin(), ie = term->parameters().end(); ii != ie; ++ii) { if (ii != ib) *m_output << ", "; *m_output << name(*ii) << " : "; print_term((*ii)->type(), false); } *m_output << ") > "; if (term->result()) print_term(term->result(), true); else *m_output << "NULL"; *m_output << ";\n"; }
void DisassemblerContext::setup_function(const ValuePtr<Function>& function) { for (Function::ParameterList::const_iterator ii = function->parameters().begin(), ie = function->parameters().end(); ii != ie; ++ii) setup_term_definition(*ii); setup_term(function->result_type()); for (Function::BlockList::const_iterator ii = function->blocks().begin(), ie = function->blocks().end(); ii != ie; ++ii) { const ValuePtr<Block>& block = *ii; setup_term_name(block); for (Block::PhiList::const_iterator ji = block->phi_nodes().begin(), je = block->phi_nodes().end(); ji != je; ++ji) m_names.insert(std::make_pair(*ji, make_term_name(*ji, function))); for (Block::InstructionList::const_iterator ji = block->instructions().begin(), je = block->instructions().end(); ji != je; ++ji) m_names.insert(std::make_pair(*ji, make_term_name(*ji, function))); for (Function::BlockList::const_iterator ji = function->blocks().begin(), je = function->blocks().end(); ji != je; ++ji) { setup_term_name(*ji); setup_block(*ji); } } }
void DisassemblerContext::print_term_definition(const ValuePtr<>& term, bool global) { *m_output << name(term) << " = "; switch (term->term_type()) { case term_functional: { if (global) *m_output << "define "; print_functional_term(value_cast<FunctionalValue>(term), false); *m_output << ";\n"; break; } case term_function_type: { if (global) *m_output << "define "; print_function_type_term(value_cast<FunctionType>(term), false); *m_output << ";\n"; break; } case term_instruction: { print_instruction_term(value_cast<Instruction>(term)); break; } case term_phi: { print_phi_term(value_cast<Phi>(term)); break; } case term_global_variable: { ValuePtr<GlobalVariable> gvar = value_cast<GlobalVariable>(term); *m_output << "global "; if (gvar->constant()) *m_output << "const "; print_term(gvar->value_type(), true); if (gvar->value()) { *m_output << ' '; print_term(gvar->value(), true); } *m_output << ";\n"; return; } case term_function: { print_function(value_cast<Function>(term)); return; } case term_function_parameter: { ValuePtr<FunctionParameter> parameter = value_cast<FunctionParameter>(term); ValuePtr<Function> function = parameter->function(); unsigned n = 0; for (Function::ParameterList::const_iterator ii = function->parameters().begin(), ie = function->parameters().end(); ii != ie; ++ii, ++n) { if (parameter == *ii) { *m_output << "[function parameter " << n << "]\n"; return; } } *m_output << "[invalid function parameter]\n"; return; } case term_apply: { if (global) *m_output << "define "; print_apply_term(value_cast<ApplyType>(term), false); *m_output << ";\n"; return; } case term_exists: { if (global) *m_output << "define "; print_exists(value_cast<Exists>(term), false); *m_output << ";\n"; return; } case term_recursive: { print_recursive(value_cast<RecursiveType>(term)); return; } case term_recursive_parameter: *m_output << "[recursive parameter]\n"; return; case term_parameter_placeholder: *m_output << "[parameter placeholder]\n"; return; case term_upref_null: *m_output << "upref_null\n"; return; default: PSI_FAIL("unexpected term type - cannot print a definition"); } }
void DisassemblerContext::setup_term_definition(const ValuePtr<>& term) { if (!m_defined_terms.insert(term).second) return; setup_term_name(term); switch (term->term_type()) { case term_recursive: { ValuePtr<RecursiveType> recursive = value_cast<RecursiveType>(term); for (RecursiveType::ParameterList::const_iterator ii = recursive->parameters().begin(), ie = recursive->parameters().end(); ii != ie; ++ii) { setup_term_name(*ii); setup_term((*ii)->type()); } if (recursive->result()) setup_term(recursive->result()); break; } case term_global_variable: { ValuePtr<GlobalVariable> gvar = value_cast<GlobalVariable>(term); setup_term(gvar->value_type()); if (gvar->value()) setup_term(gvar->value()); break; } case term_function: { ValuePtr<Function> function = value_cast<Function>(term); setup_function(function); break; } case term_function_parameter: { ValuePtr<FunctionParameter> param = value_cast<FunctionParameter>(term); setup_term(param->type()); break; } case term_instruction: { class MyVisitor : public InstructionVisitor { DisassemblerContext *m_self; public: MyVisitor(DisassemblerContext *self) : m_self(self) {} virtual void next(ValuePtr<>& v) {if (v) m_self->setup_term(v);} }; MyVisitor my_visitor(this); ValuePtr<Instruction> insn = value_cast<Instruction>(term); insn->instruction_visit(my_visitor); m_local_definitions[insn->block()].push_back(insn); break; } case term_phi: { ValuePtr<Phi> phi = value_cast<Phi>(term); const std::vector<PhiEdge>& edges = phi->edges(); for (std::vector<PhiEdge>::const_iterator ii = edges.begin(), ie = edges.end(); ii != ie; ++ii) { setup_term(ii->block); setup_term(ii->value); } break; } default: setup_term(term); break; } }