summaryrefslogtreecommitdiff
path: root/gnu/egcs/gcc/function.c
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2002-12-02 09:00:27 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2002-12-02 09:00:27 +0000
commit22703df0df76accb65607f28070a9771b5bb42de (patch)
tree2f2aa0ebf948ee4580b10bb0a41b7f258b40d0e8 /gnu/egcs/gcc/function.c
parent560fab27442ac85618b1720e90581c295ae1ea83 (diff)
Import propolice (http://www.trl.ibm.com/projects/security/ssp), a stack
attack protection scheme, into gcc. This protection is enabled by default. It can be turned off by using the -fno-stack-protector flag. Code by Hiroaki Etoh (etoh at jp dot ibm dot com); work on openbsd-specific integration by fgsch@, deraadt@ and myself; tests by fgsch@, naddy@ and myself; beer drinking by myself. Please note that system upgrades with this new code will require a new libc and ld.so to be build and installed before the propolice-enabled compiler can be installed.
Diffstat (limited to 'gnu/egcs/gcc/function.c')
-rw-r--r--gnu/egcs/gcc/function.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/gnu/egcs/gcc/function.c b/gnu/egcs/gcc/function.c
index edd0bca1216..88523dfcc79 100644
--- a/gnu/egcs/gcc/function.c
+++ b/gnu/egcs/gcc/function.c
@@ -58,6 +58,7 @@ Boston, MA 02111-1307, USA. */
#include "obstack.h"
#include "toplev.h"
#include "hash.h"
+#include "protector.h"
#ifndef TRAMPOLINE_ALIGNMENT
#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
@@ -430,6 +431,8 @@ struct temp_slot
/* The size of the slot, including extra space for alignment. This
info is for combine_temp_slots. */
HOST_WIDE_INT full_size;
+ /* Boundary mark of a character array and the others. This info is for propolice */
+ int boundary_mark;
};
/* List of all temporaries allocated, both available and in use. */
@@ -449,6 +452,11 @@ int var_temp_slot_level;
until no longer needed. CLEANUP_POINT_EXPRs define the lifetime
of TARGET_EXPRs. */
int target_temp_slot_level;
+
+/* Current boundary mark for character arrays. */
+
+int temp_boundary_mark;
+
/* This structure is used to record MEMs or pseudos used to replace VAR, any
SUBREGs of VAR, and any MEMs containing VAR as an address. We need to
@@ -931,6 +939,10 @@ assign_stack_temp_for_type (mode, size, keep, type)
int align;
int alias_set;
struct temp_slot *p, *best_p = 0;
+ int char_array = type && (TREE_TYPE (type)==char_type_node
+ || (TREE_TYPE (type)
+ && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
+ && TYPE_PRECISION (TREE_TYPE (type)) == 8));
/* If SIZE is -1 it means that somebody tried to allocate a temporary
of a variable size. */
@@ -963,7 +975,8 @@ assign_stack_temp_for_type (mode, size, keep, type)
&& (!flag_strict_aliasing
|| (alias_set && p->alias_set == alias_set))
&& (best_p == 0 || best_p->size > p->size
- || (best_p->size == p->size && best_p->align > p->align)))
+ || (best_p->size == p->size && best_p->align > p->align))
+ && (! char_array || p->boundary_mark != 0))
{
if (p->align == align && p->size == size)
{
@@ -1001,6 +1014,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
p->align = best_p->align;
p->address = 0;
p->rtl_expr = 0;
+ p->boundary_mark = best_p->boundary_mark;
p->next = temp_slots;
temp_slots = p;
@@ -1062,6 +1076,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
p->full_size = frame_offset - frame_offset_old;
#endif
p->address = 0;
+ p->boundary_mark = char_array?++temp_boundary_mark:0;
p->next = temp_slots;
temp_slots = p;
}
@@ -1186,14 +1201,16 @@ combine_temp_slots ()
int delete_q = 0;
if (! q->in_use && GET_MODE (q->slot) == BLKmode)
{
- if (p->base_offset + p->full_size == q->base_offset)
+ if (p->base_offset + p->full_size == q->base_offset &&
+ p->boundary_mark == q->boundary_mark)
{
/* Q comes after P; combine Q into P. */
p->size += q->size;
p->full_size += q->full_size;
delete_q = 1;
}
- else if (q->base_offset + q->full_size == p->base_offset)
+ else if (q->base_offset + q->full_size == p->base_offset &&
+ p->boundary_mark == q->boundary_mark)
{
/* P comes after Q; combine P into Q. */
q->size += p->size;
@@ -1702,7 +1719,7 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
if (regno < max_parm_reg)
new = parm_reg_stack_loc[regno];
if (new == 0)
- new = assign_stack_local (decl_mode, GET_MODE_SIZE (decl_mode), 0);
+ new = assign_stack_local_for_pseudo_reg (decl_mode, GET_MODE_SIZE (decl_mode), 0);
}
PUT_MODE (reg, decl_mode);
@@ -3860,7 +3877,8 @@ instantiate_virtual_regs_1 (loc, object, extra_insns)
constant with that register. */
temp = gen_reg_rtx (Pmode);
XEXP (x, 0) = new;
- if (validate_change (object, &XEXP (x, 1), temp, 0))
+ if (validate_change (object, &XEXP (x, 1), temp, 0)
+ && ! flag_propolice_protection)
emit_insn_before (gen_move_insn (temp, new_offset), object);
else
{