about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--helpers.cc53
-rw-r--r--helpers.hh2
-rw-r--r--scout.cc6
-rw-r--r--trace-call.cc11
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)