void CfgEmitter::selectFunctionCallees(const Function::Ptr &function) { // Use an iteration rather than a traversal because we want to consider all vertices that belong to the function, including // those not reachable from the entry vertex. BOOST_FOREACH (const ControlFlowGraph::VertexNode &vertex, graph_.vertices()) { if (vertexOrganization(vertex).isSelected() && owningFunction(vertex) == function) { BOOST_FOREACH (const ControlFlowGraph::EdgeNode &edge, vertex.outEdges()) { if (isInterFunctionEdge(edge)) { if (!edgeOrganization(edge).isSelected()) { edgeOrganization(edge).select(); edgeOrganization(edge).label(edgeLabel(edge)); edgeOrganization(edge).attributes(edgeAttributes(edge)); } Organization &tgt = vertexOrganization(edge.target()); if (!tgt.isSelected()) { tgt.select(); Function::Ptr callee = owningFunction(edge.target()); if (callee && edge.target()->value().type() == V_BASIC_BLOCK && edge.target()->value().address() == callee->address()) { // target is the entry block of a function tgt.label(functionLabel(callee)); tgt.attributes(functionAttributes(callee)); } else { // target is some block that isn't a function entry tgt.label(vertexLabel(edge.target())); tgt.attributes(vertexAttributes(edge.target())); } } } } } }
bool sortFunctionsByAddress(const Function::Ptr &a, const Function::Ptr &b) { ASSERT_not_null(a); ASSERT_not_null(b); return a->address() < b->address(); }