Advertisement
Guest User

Untitled

a guest
May 23rd, 2019
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.95 KB | None | 0 0
  1. #include <iostream>
  2. #include <cassert>
  3. #include <set>
  4. #include <utility>
  5. #include <algorithm>
  6.  
  7. // This is the first gcc header to be included
  8. #include "gcc-plugin.h"
  9. #include "plugin-version.h"
  10.  
  11. #include "cp/cp-tree.h"
  12. #include "context.h"
  13. #include "function.h"
  14. #include "internal-fn.h"
  15. #include "is-a.h"
  16. #include "predict.h"
  17. #include "basic-block.h"
  18. #include "tree.h"
  19. #include "tree-ssa-alias.h"
  20. #include "gimple-expr.h"
  21. #include "gimple.h"
  22. #include "gimple-ssa.h"
  23. #include "tree-pretty-print.h"
  24. #include "tree-pass.h"
  25. #include "tree-ssa-operands.h"
  26. #include "tree-phinodes.h"
  27. #include "gimple-pretty-print.h"
  28. #include "gimple-iterator.h"
  29. #include "gimple-walk.h"
  30. #include "diagnostic.h"
  31. #include "stringpool.h"
  32. #include "attribs.h"
  33.  
  34. #include "ssa-iterators.h"
  35.  
  36. #include "print-tree.h"
  37. #include "gimple.h"
  38.  
  39. // We must assert that this plugin is GPL compatible
  40. int plugin_is_GPL_compatible;
  41.  
  42. static struct plugin_info ptr_assign_plugin_info =
  43. { "1.0", "Find pointer assign plugin" };
  44.  
  45.  
  46. namespace {
  47.     const pass_data warn_unused_result_cxx_data =
  48.     {
  49.         GIMPLE_PASS,
  50.         "ptr_assign_pass"/* name */
  51.         OPTGROUP_NONE,      /* optinfo_flags */
  52.         TV_NONE,            /* tv_id */
  53.         PROP_gimple_any,    /* properties_required */
  54.         0,                  /* properties_provided */
  55.         0,                  /* properties_destroyed */
  56.         0,                  /* todo_flags_start */
  57.         0                   /* todo_flags_finish */
  58.     };
  59.  
  60.     struct find_ptr_assign_cxx : gimple_opt_pass
  61.     {
  62.         find_ptr_assign_cxx(gcc::context *ctx)
  63.             : gimple_opt_pass(warn_unused_result_cxx_data, ctx)
  64.         {
  65.         }
  66.  
  67.         static bool is_memref(tree type)
  68.         {
  69.             if (TREE_CODE(type) == MEM_REF)
  70.                 return true;
  71.  
  72.             return false;
  73.         }
  74.  
  75.         static void add_ptr_ptrint_call(void)
  76.         {
  77.  
  78.         }
  79.  
  80.         void instrument_ptr_writes(function *fun)
  81.         {
  82.             basic_block bb;
  83.  
  84.             FOR_ALL_BB_FN(bb, fun) {
  85.                 gimple_stmt_iterator gsi;
  86.                 for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
  87.                     //gimple stmt = gsi_stmt(gsi);
  88.                     gimple *stmt = gsi_stmt(gsi);
  89.  
  90.                     switch (gimple_code(stmt)) {
  91.                         case GIMPLE_ASSIGN:
  92.                             {
  93.                                 tree lhs = gimple_assign_lhs(stmt);
  94.                                 //tree rhs1 = gimple_assign_rhs1(stmt);
  95.  
  96.                                 //std::cerr << "# Stmt:\n";
  97.                                 //print_gimple_stmt (stderr, stmt, 0, 0);
  98.                                 //std::cerr << "# Tree:\n";
  99.                                 //debug_tree(lhs);
  100.                                 //std::cerr << "\n";
  101.                                 //break;
  102.  
  103.                                 if (lhs && is_memref(lhs)) {
  104.                                     location_t loc = gimple_location(stmt);
  105.                                     warning_at(loc, 0, "Pointer assign lhs");
  106.                                     print_gimple_stmt (stderr, stmt, 0, 0);
  107.  
  108.                                     /* Add call */
  109.                                     tree function_fn;
  110.                                     tree function_fn_type;
  111.  
  112.                                     function_fn_type = build_function_type_list(
  113.                                             /* return */ void_type_node,
  114.                                             /* arg (ptr) */ const_ptr_type_node,
  115.                                             NULL_TREE);
  116.                                     function_fn = build_fn_decl("print_ptr",
  117.                                             function_fn_type);
  118.  
  119.                                     TREE_PUBLIC(function_fn) = 1;
  120.  
  121.                                     gimple *call = gimple_build_call(function_fn, 1, lhs);
  122.                                     gimple_stmt_iterator stmt_gsi = gsi_for_stmt(stmt);
  123.                                     gsi_insert_before(&stmt_gsi, call, GSI_NEW_STMT);
  124.                                 }
  125.  
  126.                                 break;
  127.                             }
  128.                         default:
  129.                             // Do nothing
  130.                             break;
  131.                     }
  132.                 }
  133.  
  134.             }
  135.         }
  136.  
  137.         virtual unsigned int execute(function *fun) override
  138.         {
  139.             instrument_ptr_writes(fun);
  140.  
  141.             basic_block bb;
  142.  
  143.             FOR_ALL_BB_FN(bb, fun) {
  144.                 gimple_stmt_iterator gsi;
  145.                 for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
  146.                     //gimple stmt = gsi_stmt(gsi);
  147.                     gimple *stmt = gsi_stmt(gsi);
  148.  
  149.                     switch (gimple_code(stmt)) {
  150.                         case GIMPLE_CALL:
  151.                             {
  152.                                 tree current_fn_decl = gimple_call_fndecl(stmt);
  153.                                 std::cerr << "# Fn Call Tree:\n";
  154.                                 debug_tree(current_fn_decl);
  155.                                 std::cerr << "\n";
  156.  
  157.                                 unsigned nargs = gimple_call_num_args(stmt);
  158.                                 for (unsigned i = 0; i <nargs; i++) {
  159.                                     tree arg = gimple_call_arg(stmt, i);
  160.                                 }
  161.  
  162.                                 break;
  163.                             }
  164.                         default:
  165.                             // Do nothing
  166.                             break;
  167.                     }
  168.                 }
  169.  
  170.             }
  171.  
  172.             return 0;
  173.         }
  174.  
  175.         virtual find_ptr_assign_cxx *clone() override
  176.         {
  177.             // Do not clone ourselves
  178.             return this;
  179.         }
  180.     };
  181.  
  182.  
  183. }
  184.  
  185. int plugin_init(struct plugin_name_args *plugin_info,
  186.         struct plugin_gcc_version *version)
  187. {
  188.     // We check the current gcc loading this plugin against the gcc we used to
  189.     // created this plugin
  190.     if (!plugin_default_version_check (version, &gcc_version))
  191.     {
  192.         std::cerr << "This GCC plugin is for version " << GCCPLUGIN_VERSION_MAJOR
  193.             << "." << GCCPLUGIN_VERSION_MINOR << "\n";
  194.         return 1;
  195.     }
  196.     std::cout << "Plugin successfully initialized\n";
  197.  
  198.     register_callback(plugin_info->base_name,
  199.             /* event */ PLUGIN_INFO,
  200.             /* callback */ NULL,
  201.             /* user_data */ &ptr_assign_plugin_info);
  202.  
  203.     // Register the phase right after cfg
  204.     struct register_pass_info pass_info;
  205.  
  206.     pass_info.pass = new find_ptr_assign_cxx(g); // "g" is a global gcc::context pointer
  207.     pass_info.reference_pass_name = "cfg";
  208.     //pass_info.reference_pass_name = "ssa";
  209.     pass_info.ref_pass_instance_number = 1;
  210.     pass_info.pos_op = PASS_POS_INSERT_AFTER;
  211.  
  212.     register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
  213.             &pass_info);
  214.  
  215.     return 0;
  216. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement