Index: gcc/gcc/ctrl-intg.c |
diff --git a/gcc/gcc/ctrl-intg.c b/gcc/gcc/ctrl-intg.c |
deleted file mode 100644 |
index 61e10198c5dbe34a1f99332bf8825fcd715c5d93..0000000000000000000000000000000000000000 |
--- a/gcc/gcc/ctrl-intg.c |
+++ /dev/null |
@@ -1,376 +0,0 @@ |
-/* Patch RTL to enforce control flow integrity for GCC. |
- Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002, 2003, |
- 2004, 2005, 2007 |
- Free Software Foundation, Inc. |
- |
-This file is part of GCC. |
- |
-GCC is free software; you can redistribute it and/or modify it under |
-the terms of the GNU General Public License as published by the Free |
-Software Foundation; either version 3, or (at your option) any later |
-version. |
- |
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
-WARRANTY; without even the implied warranty of MERCHANTABILITY or |
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
-for more details. |
- |
-You should have received a copy of the GNU General Public License |
-along with GCC; see the file COPYING3. If not see |
-<http://www.gnu.org/licenses/>. */ |
- |
-/* This file is compiled twice: once for the generator programs, |
- once for the compiler. */ |
-#ifdef GENERATOR_FILE |
-#include "bconfig.h" |
-#else |
-#include "config.h" |
-#endif |
- |
-#include "system.h" |
-#include "coretypes.h" |
-#include "tm.h" |
-#include "rtl.h" |
-#include "tree-pass.h" |
-#include "expr.h" |
- |
-/* These headers all define things which are not available in |
- generator programs. */ |
-#ifndef GENERATOR_FILE |
-#include "tree.h" |
-#include "real.h" |
-#include "flags.h" |
-#include "hard-reg-set.h" |
-#include "basic-block.h" |
-#endif |
- |
-static bool |
-gate_func (void) { |
- return getenv("NACLSHUTDOWN") == NULL; |
- /* return flag_control_integrity; */ |
-} |
- |
-static void |
-process_call_insn(rtx insn) { |
- rtx return_value_expr, call_expr, mem_expr, addr_expr, parallel_expr; |
- rtx sp_size_expr, tls_disp; |
- |
- /* |
- * Get the expression to be examined from the instruction. |
- */ |
- call_expr = XEXP (insn, 5); |
- |
- if (GET_CODE (call_expr) == PARALLEL) { |
- /* |
- * Calls that pop the stack use a PARALLEL containing a CALL and a SET. |
- */ |
- rtx vec1 = XVECEXP (call_expr, 0, 1); |
- parallel_expr = call_expr; |
- tls_disp = NULL_RTX; |
- |
- if (TARGET_64BIT && |
- GET_CODE(vec1) == UNSPEC && XINT(vec1, 1) == UNSPEC_TPOFF) { |
- /* |
- * TLS calls use a PARALLEL containing a CALL and UNSPEC_TPOFF. |
- */ |
- tls_disp = XVECEXP(vec1, 0, 0); |
- gcc_assert(GET_CODE(tls_disp) == SYMBOL_REF); |
- } else { |
- sp_size_expr = XEXP (XEXP (vec1, 1), 1); |
- } |
- call_expr = XVECEXP (call_expr, 0, 0); |
- } |
- else { |
- parallel_expr = NULL_RTX; |
- } |
- |
- /* |
- * Get the call expression and return value (if any). |
- */ |
- if (GET_CODE (call_expr) == SET) { |
- /* |
- * Functions with return values use a SET instruction wrapper. |
- * Get the call out of the set if needed. |
- */ |
- return_value_expr = XEXP (call_expr, 0); |
- call_expr = XEXP (call_expr, 1); |
- } |
- else { |
- return_value_expr = NULL_RTX; |
- } |
- |
- /* |
- * Extract the target address expression of the function. |
- */ |
- mem_expr = XEXP (call_expr, 0); |
- |
- /* |
- * Get the address expression from the MEM. |
- */ |
- |
- gcc_assert (GET_CODE (mem_expr) == MEM); |
- addr_expr = XEXP (mem_expr, 0); |
- |
- if (GET_CODE (addr_expr) != SYMBOL_REF) { |
- rtx insns_head, call, call_insn; |
- int enable_print; |
- |
- { |
- static int calls_converted=0; |
- static int printed=0; |
- char* call_limit = getenv("NONACLCALL"); |
- char* name_compare = getenv("NACLBINS"); |
- if (name_compare && strcmp(main_input_filename, name_compare) > 0) { |
- if (printed == 0) { |
- fprintf(stderr, "NACL: name test shut off\n"); |
- printed = 1; |
- } |
- return; |
- } |
- |
- ++calls_converted; |
- enable_print = (call_limit && calls_converted == atoi(call_limit)); |
- if (call_limit && calls_converted > atoi(call_limit)) { |
- if (printed == 0) { |
- fprintf(stderr, "NACL: '%s' call limit exceeded\n", |
- main_input_filename); |
- printed = 1; |
- } |
- return; |
- } |
- /* fprintf(stderr, "NACL: converted call %d\n", calls_converted); */ |
- } |
- |
- if (return_value_expr && parallel_expr) { |
- if (getenv("NACLDBGBOTH")) return; |
- } else if (return_value_expr) { |
- if (getenv("NACLDBGRET")) return; |
- } else if (parallel_expr) { |
- if (getenv("NACLDBGPAR")) return; |
- } else { |
- if (SIBLING_CALL_P (insn)) { |
- if (getenv("NACLDBGNONE1")) return; |
- } else { |
- char* str = getenv("NACLDBGNONE2"); |
- if (str) { |
- FILE* fp = fopen("/home/sehr/NACLDBGCOUNT", "r+"); |
- int current_count; |
- fscanf(fp, "%d\n", ¤t_count); |
- fprintf(stderr, "NACLDEBUGCOUNT = %d \n", current_count); |
- rewind(fp); |
- fprintf(fp, "%d\n", current_count+1); |
- fclose(fp); |
- if (current_count > atoi(str)) { |
- fprintf(stderr, "NACLDEBUGCOUNT %d exceeded %d\n", |
- current_count, atoi(str)); |
- return; |
- } |
- } |
- } |
- } |
- |
- start_sequence (); |
- |
- if (enable_print) { |
- fprintf(stderr, "Before:\n"); |
- print_rtl_single(stderr, insn); |
- } |
- |
- /* |
- * Force the called function address to be in a register. |
- */ |
- addr_expr = force_reg (GET_MODE (addr_expr), addr_expr); |
- |
-#define gen_nacl(suffix) \ |
- (TARGET_64BIT ? gen_nacl ## suffix ## di : \ |
- gen_nacl ## suffix ## si) |
- /* |
- * Generate the appropriate template for the call |
- */ |
- if (return_value_expr && parallel_expr) { |
- if (!tls_disp) { |
- call = gen_nacl(call_value_pop) (return_value_expr, addr_expr, |
- XEXP (call_expr, 1), sp_size_expr); |
- } else { |
- call = gen_naclcall_tls(mem_expr, XEXP (call_expr, 1)); |
- } |
- } else if (return_value_expr) { |
- if (SIBLING_CALL_P (insn)) { |
- call = gen_nacl(sibcall_value) (return_value_expr, |
- addr_expr, XEXP (call_expr, 1)); |
- } else { |
- call = gen_nacl(call_value) (return_value_expr, |
- addr_expr, XEXP (call_expr, 1)); |
- } |
- } else if (parallel_expr) { |
- call = gen_nacl(call_pop) (addr_expr, XEXP (call_expr, 1), |
- sp_size_expr); |
- } else { |
- if (SIBLING_CALL_P (insn)) { |
- call = gen_nacl(sibcall) (addr_expr, XEXP (call_expr, 1)); |
- } else { |
- call = gen_nacl(call) (addr_expr, XEXP (call_expr, 1)); |
- } |
- } |
- |
- call_insn = emit_call_insn (call); |
- |
- RTL_CONST_CALL_P (call_insn) = RTL_CONST_CALL_P (insn); |
- RTL_PURE_CALL_P (call_insn) = RTL_PURE_CALL_P (insn); |
- SIBLING_CALL_P (call_insn) = SIBLING_CALL_P (insn); |
- REG_NOTES (call_insn) = REG_NOTES (insn); |
- CALL_INSN_FUNCTION_USAGE (call_insn) = CALL_INSN_FUNCTION_USAGE (insn); |
- |
- insns_head = get_insns (); |
- |
- if (enable_print) { |
- fprintf(stderr, "After: (%d, %d) \n", RTL_CONST_OR_PURE_CALL_P (call_insn), |
- SIBLING_CALL_P (call_insn)); |
- print_rtl(stderr, insns_head); |
- } |
- |
- end_sequence (); |
- emit_insn_before (insns_head, insn); |
- |
- delete_insn (insn); |
- } |
-} |
- |
- |
-static void |
-process_jump_insn(rtx insn) { |
- rtx par_expr, set_expr, addr_expr; |
- rtx jmp; |
- |
- /* |
- * Get the contained expression. |
- */ |
- par_expr = XEXP (insn, 5); |
- |
- if (GET_CODE (par_expr) == PARALLEL) { |
- set_expr = XVECEXP (par_expr, 0, 0); |
- |
- if (GET_CODE (set_expr) == SET) { |
- addr_expr = XEXP (set_expr, 1); |
- |
- if (GET_CODE (addr_expr) == IF_THEN_ELSE) { |
- /* |
- * Ordinary branches uses parallel/set/if_then_else. |
- * Leave them unmodified. |
- */ |
- } |
- else { |
- /* |
- * A table indirect jump instruction has parallel/set/other |
- */ |
- rtx insns_head, jmp_insn; |
- int enable_print; |
- |
- { |
- static int calls_converted=0; |
- static int printed=0; |
- char* name_compare = getenv("NACLBINS"); |
- char* call_limit = getenv("NONACLJMP"); |
- if (name_compare && strcmp(main_input_filename, name_compare) > 0) { |
- fprintf(stderr, "NACL: name test shut off\n"); |
- return; |
- } |
- |
- ++calls_converted; |
- enable_print = (call_limit && calls_converted == atoi(call_limit)); |
- if (call_limit && calls_converted > atoi(call_limit)) { |
- if (printed == 0) { |
- fprintf(stderr, "NACL: '%s' call limit exceeded\n", |
- main_input_filename); |
- printed = 1; |
- } |
- return; |
- } |
- /*fprintf(stderr, "NACL: converted branch %d\n", calls_converted);*/ |
- } |
- |
- start_sequence (); |
- |
- if (enable_print) { |
- fprintf(stderr, "Before:\n"); |
- print_rtl_single(stderr, insn); |
- } |
- addr_expr = force_reg (GET_MODE (addr_expr), addr_expr); |
- jmp = gen_nacl(jmp_table) (addr_expr, |
- XEXP (XEXP (XVECEXP (par_expr, 0, 1), 0), 0)); |
- jmp_insn = emit_jump_insn (jmp); |
- |
- if (JUMP_LABEL (insn) != NULL_RTX) { |
- JUMP_LABEL (jmp_insn) = JUMP_LABEL (insn); |
- LABEL_NUSES (JUMP_LABEL (insn))++; |
- } |
- |
- insns_head = get_insns (); |
- if (enable_print) { |
- fprintf(stderr, "After %p:\n", (void*) JUMP_LABEL (jmp_insn)); |
- print_rtl(stderr, insns_head); |
- } |
- |
- end_sequence (); |
- emit_insn_before (insns_head, insn); |
- |
- delete_insn (insn); |
- } |
- } |
- } else { |
- /* |
- * Other indirect jumps remain to be identified. |
- */ |
- } |
-} |
- |
-extern int nacl_special_commands; |
- |
-static int |
-execute_func (void) { |
- basic_block bb; |
- |
- int save_nacl_special_commands = nacl_special_commands; |
- nacl_special_commands = 1; |
- |
- if (getenv("NACLSHUTDOWN4")) return 0; |
- /* Even if reload is not yet completed - fake it to make reload impossible */ |
- FOR_EACH_BB (bb) { |
- rtx insn, last; |
- |
- if (getenv("NACLSHUTDOWN3")) continue; |
- for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb)); insn != last; |
- insn = NEXT_INSN(insn)) { |
- if (getenv("NACLSHUTDOWN2")) continue; |
- if (JUMP_P (insn)) { |
- if (flag_control_integrity) |
- process_jump_insn (insn); |
- } |
- if (CALL_P (insn)) { |
- if (flag_control_integrity) |
- process_call_insn (insn); |
- } |
- } |
- } |
- |
- nacl_special_commands = save_nacl_special_commands; |
- return 0; |
-} |
- |
-struct rtl_opt_pass pass_control_integrity = { |
- { |
- RTL_PASS, |
- "ctrl_intg_insert", |
- gate_func, |
- execute_func, |
- 0, /* sub */ |
- 0, /* next */ |
- 0, /* static_pass_number */ |
- 0, /* tv_id */ |
- 0, /* properties_required */ |
- 0, /* properties_provided */ |
- 0, /* properties_destroyed */ |
- TODO_dump_func, /* todo_flags_start */ |
- TODO_dump_func, /* todo_flags_finish */ |
- } |
-}; |