diff options
| author | Nguyễn Gia Phong <cnx@loang.net> | 2025-10-15 18:24:14 +0900 |
|---|---|---|
| committer | Nguyễn Gia Phong <cnx@loang.net> | 2025-10-15 18:26:47 +0900 |
| commit | 06dff5537cf4b304aaaa7ea55b5899138fc3b8f4 (patch) | |
| tree | 8870a263b6f241e402c12e2bd5fb66f1162d3621 | |
| parent | 5562397b73d4cde06e773f00485e16406853e1fd (diff) | |
| download | taosc-06dff5537cf4b304aaaa7ea55b5899138fc3b8f4.tar.gz | |
Refactor C++ stuff
Constantize all the things!
| -rw-r--r-- | helpers.cc | 53 | ||||
| -rw-r--r-- | helpers.hh | 2 | ||||
| -rw-r--r-- | scout.cc | 6 | ||||
| -rw-r--r-- | trace-call.cc | 11 |
4 files changed, 41 insertions, 31 deletions
diff --git a/helpers.cc b/helpers.cc index c02957e..7bb1215 100644 --- a/helpers.cc +++ b/helpers.cc @@ -51,39 +51,48 @@ die_for (Address address, std::string const& message) std::exit (1); } +static CodeRegion* +find_region (CodeSource& cs, Address address) +{ + if (!cs.isCode (address)) + die_for (address, "no instruction at"); + std::set <CodeRegion*> regions; + if (cs.findRegions (address, regions) != 1) + die_for (address, "not exactly one region found spanning"); + for (auto* const cr : regions) + return cr; + std::unreachable (); +} + /// Find next basic block's entry after given address, reparsing if necessary static Block* -next_block (CodeObject& co, CodeRegion* region, Address address) +next_block (CodeObject& co, CodeRegion* cr, Address address) { - auto* blk = co.findBlockByEntry (region, address); + auto* blk = co.findBlockByEntry (cr, address); if (blk != nullptr) return blk; co.parse (address, true); - blk = co.findBlockByEntry (region, address); - return (blk != nullptr) ? blk : co.findNextBlock (region, address); + blk = co.findBlockByEntry (cr, address); + return (blk != nullptr) ? blk : co.findNextBlock (cr, address); } Block* find_block (CodeSource& cs, CodeObject& co, Address address) { - if (!cs.isCode (address)) - die_for (address, "no instruction at"); - std::set <CodeRegion*> regions; - if (cs.findRegions (address, regions) != 1) - die_for (address, "not exactly 1 region found for instruction at"); - for (auto* region : regions) + auto* const cr = find_region (cs, address); + std::set <Block*> blocks; + if (co.findBlocks (cr, address, blocks) > 0) { - std::set <Block*> blocks; - if (co.findBlocks (region, address, blocks) > 0) - for (auto* blk : blocks) // TODO: choose the best block - return blk; - auto* blk = next_block (co, region, region->low ()); - while (blk != nullptr && address > blk->last ()) - blk = next_block (co, region, blk->end ()); - if (blk == nullptr) - die_for (address, "no block found for instruction at"); - assert (address >= blk->start () && address < blk->end ()); - return blk; + if (blocks.size () > 1) + die_for (address, "more than one block found spanning"); + for (auto* const blk : blocks) + return blk; } - std::unreachable (); + auto* blk = next_block (co, cr, cr->low ()); + while (blk != nullptr && address > blk->last ()) + blk = next_block (co, cr, blk->end ()); + if (blk == nullptr) + die_for (address, "no block found spanning"); + assert (address >= blk->start () && address < blk->end ()); + return blk; } diff --git a/helpers.hh b/helpers.hh index 0c015b1..9843418 100644 --- a/helpers.hh +++ b/helpers.hh @@ -33,7 +33,7 @@ char const* parse_args (int, char const* const*); /// then terminate the program with exit code 1 void die_for (Dyninst::Address, std::string const&); -/// Find block containing given address +/// Aggressively search for the block spanning the given address Dyninst::ParseAPI::Block* find_block (Dyninst::ParseAPI::SymtabCodeSource&, Dyninst::ParseAPI::CodeObject&, Dyninst::Address); diff --git a/scout.cc b/scout.cc index ae2f7c6..0bcce84 100644 --- a/scout.cc +++ b/scout.cc @@ -39,18 +39,18 @@ main (int argc, char** argv) if (std::cin.fail ()) break; std::cout << std::hex << address; - auto* block = find_block (cs, co, address); + auto* const block = find_block (cs, co, address); if (block->containingFuncs () < 1) die_for (address, "no function found containing instruction at"); std::vector <Dyninst::ParseAPI::Function*> functions; block->getFuncs (functions); std::set <Dyninst::Address> seen; - for (auto* fun : functions) + for (auto* const fun : functions) for (auto const& return_block : fun->returnBlocks ()) { std::set <Dyninst::ParseAPI::Block*> post_dominates; fun->getImmediatePostDominates (return_block, post_dominates); - for (auto* pd : post_dominates) + for (auto* const pd : post_dominates) if (seen.insert (pd->start ()).second) std::cout << ' ' << std::hex << pd->start (); } diff --git a/trace-call.cc b/trace-call.cc index d154b4f..9d22599 100644 --- a/trace-call.cc +++ b/trace-call.cc @@ -38,7 +38,7 @@ main (int argc, char** argv) std::cin >> std::hex >> return_address; if (std::cin.fail ()) break; - auto* block = find_block (cs, co, return_address); + auto* const block = find_block (cs, co, return_address); // Each function call creates an interprocedure edge, // hence its basic block ends with the call site. // The control flow then naturally goes to the next basic block @@ -50,11 +50,12 @@ main (int argc, char** argv) std::vector <Dyninst::ParseAPI::Function*> functions; block->getFuncs (functions); Dyninst::Address call_address = 0; - for (auto* fun : functions) - for (auto* call_edge : fun->callEdges ()) + for (auto* const fun : functions) + for (auto* const call_edge : fun->callEdges ()) { - auto* call_block = call_edge->src (); - auto* return_block = fun->getImmediatePostDominator (call_block); + auto* const call_block = call_edge->src (); + auto* const return_block + = fun->getImmediatePostDominator (call_block); if (return_block == nullptr || *return_block != *block) continue; if (call_address != 0) |
