Open an IR and print every path from some point to some other point.
#include <fstream>
#include <iomanip>
#include <iostream>
#include <set>
#include <vector>
auto Flags = Os.flags();
Os << "0x" << std::hex << std::setw(8) << std::setfill('0') << uint64_t(A);
Os.flags(Flags);
return Os;
}
class PrintPathsVisitor {
public:
using Vertex = CFG::vertex_descriptor;
void visit(Vertex V) {
Visited.insert(V);
if (V == Target) {
for (auto U : Path) {
std::cout << dyn_cast<CodeBlock>(Graph[U])->getAddress() << ", ";
}
std::cout << dyn_cast<CodeBlock>(Graph[Target])->getAddress() << "\n";
} else {
Path.push_back(V);
auto [Begin, End] = out_edges(V, Graph);
for (auto It = Begin; It != End; It++) {
auto T = target(*It, Graph);
if (Visited.find(T) == Visited.end()) {
visit(T);
}
}
Path.pop_back();
}
Visited.erase(V);
}
Vertex Target;
std::vector<Vertex> Path;
std::set<Vertex> Visited;
};
int main(int argc, char** argv) {
if (argc == 4) {
std::ifstream in(argv[1]);
I = *IoE;
}
if (!I)
return EXIT_FAILURE;
Addr Source(std::stoul(argv[2],
nullptr, 16));
Addr Target(std::stoul(argv[3],
nullptr, 16));
const auto& Cfg = I->
getCFG();
if (auto Range = Mod.findCodeBlocksAt(Source); !Range.empty()) {
SourceBlock = &*Range.begin();
} else {
std::cerr << "No block at source address " << Source << "\n";
exit(EXIT_FAILURE);
}
if (auto Range = Mod.findCodeBlocksAt(Target); !Range.empty()) {
TargetBlock = &*Range.begin();
} else {
std::cerr << "No block at target address " << Target << "\n";
exit(EXIT_FAILURE);
}
std::cout <<
"Paths from " << SourceBlock->
getAddress() <<
" to "
PrintPathsVisitor(Cfg, *TargetBlock).visit(*
getVertex(SourceBlock, Cfg));
return EXIT_SUCCESS;
}