static void stackleak_add_instrumentation(gimple_stmt_iterator *gsi) { gimple stmt; gcall *track_stack; cgraph_node_ptr node; int frequency; basic_block bb; // insert call to void pax_track_stack(void) stmt = gimple_build_call(track_function_decl, 0); track_stack = as_a_gcall(stmt); gsi_insert_after(gsi, track_stack, GSI_CONTINUE_LINKING); // update the cgraph bb = gimple_bb(track_stack); node = cgraph_get_create_node(track_function_decl); gcc_assert(node); frequency = compute_call_stmt_bb_frequency(current_function_decl, bb); cgraph_create_edge(cgraph_get_node(current_function_decl), node, track_stack, bb->count, frequency, bb->loop_depth); }
static unsigned int sancov_execute(void) { basic_block bb; /* Remove this line when this plugin and kcov will be in the kernel. if (!strcmp(DECL_NAME_POINTER(current_function_decl), DECL_NAME_POINTER(sancov_fndecl))) return 0; */ FOR_EACH_BB_FN(bb, cfun) { const_gimple stmt; gcall *gcall; gimple_stmt_iterator gsi = gsi_after_labels(bb); if (gsi_end_p(gsi)) continue; stmt = gsi_stmt(gsi); gcall = as_a_gcall(gimple_build_call(sancov_fndecl, 0)); gimple_set_location(gcall, gimple_location(stmt)); gsi_insert_before(&gsi, gcall, GSI_SAME_STMT); }
static void stackleak_check_alloca(gimple_stmt_iterator *gsi) { gimple stmt; gcall *check_alloca; tree alloca_size; cgraph_node_ptr node; int frequency; basic_block bb; // insert call to void pax_check_alloca(unsigned long size) alloca_size = gimple_call_arg(gsi_stmt(*gsi), 0); stmt = gimple_build_call(check_function_decl, 1, alloca_size); check_alloca = as_a_gcall(stmt); gsi_insert_before(gsi, check_alloca, GSI_SAME_STMT); // update the cgraph bb = gimple_bb(check_alloca); node = cgraph_get_create_node(check_function_decl); gcc_assert(node); frequency = compute_call_stmt_bb_frequency(current_function_decl, bb); cgraph_create_edge(cgraph_get_node(current_function_decl), node, check_alloca, bb->count, frequency, bb->loop_depth); }
// Collect interesting stmts for duplication static void search_interesting_stmts(struct visited *visited) { basic_block bb; bool search_ret; struct interesting_stmts *head = NULL; search_ret = is_interesting_function(current_function_decl, 0); FOR_ALL_BB_FN(bb, cfun) { gimple_stmt_iterator gsi; for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { tree first_node; gimple stmt = gsi_stmt(gsi); switch (gimple_code(stmt)) { case GIMPLE_ASM: if (!is_size_overflow_insert_check_asm(as_a_gasm(stmt))) continue; first_node = get_size_overflow_asm_input(as_a_gasm(stmt)); head = search_interesting_stmt(head, stmt, first_node, 0); break; case GIMPLE_RETURN: if (!search_ret) continue; first_node = gimple_return_retval(as_a_greturn(stmt)); if (first_node == NULL_TREE) break; head = search_interesting_stmt(head, stmt, first_node, 0); break; case GIMPLE_CALL: head = search_interesting_calls(head, as_a_gcall(stmt)); break; default: break; } } }