1 #!/usr/bin/perl -w
   2 
   3 use strict;
   4 use warnings;
   5 use bigint;
   6 use DBI;
   7 use Data::Dumper;
   8 
   9 my $db_file = shift;
  10 my $db = DBI->connect("dbi:SQLite:$db_file", "", "", {AutoCommit => 0});
  11 
  12 $db->do("PRAGMA cache_size = 800000");
  13 $db->do("PRAGMA journal_mode = OFF");
  14 $db->do("PRAGMA count_changes = OFF");
  15 $db->do("PRAGMA temp_store = MEMORY");
  16 $db->do("PRAGMA locking = EXCLUSIVE");
  17 
  18 my ($update, $sth, $fn_ptr, $ptr_to_ptr, $count);
  19 
  20 $update = $db->prepare_cached('UPDATE function_ptr set searchable = 1 where ptr = ?');
  21 $sth = $db->prepare('select distinct(ptr) from function_ptr;');
  22 $sth->execute();
  23 
  24 while ($fn_ptr = $sth->fetchrow_array()) {
  25 
  26     # following a pointer to pointer chain is too complicated for now
  27     $ptr_to_ptr = $db->selectrow_array("select function from function_ptr where ptr = '$fn_ptr' and function like '% %';");
  28     if ($ptr_to_ptr) {
  29         next;
  30     }
  31     $ptr_to_ptr = $db->selectrow_array("select function from function_ptr where ptr = '$fn_ptr' and function like '%[]';");
  32     if ($ptr_to_ptr) {
  33         next;
  34     }
  35 
  36     $count = $db->selectrow_array("select count(*) from return_states join function_ptr where return_states.function == function_ptr.function and ptr = '$fn_ptr';");
  37     # if there are too many states then bail
  38     if ($count > 1000) {
  39         next;
  40     }
  41     # if there are no states at all then don't bother recording
  42     if ($count == 0) {
  43         next;
  44     }
  45 
  46     $update->execute($fn_ptr);
  47 }
  48 
  49 $db->commit();
  50 $db->disconnect();