$DragonFly: src/gnu/usr.bin/cc34/cc_prep/patches/function.c.patch,v 1.5 2005/08/27 21:03:51 joerg Exp $ =================================================================== RCS file: /home/joerg/wd/repository/dragonflybsd/src/contrib/gcc-3.4/gcc/function.c,v retrieving revision 1.2 diff -u -r1.2 function.c --- function.c 20 Dec 2004 19:23:24 -0000 1.2 +++ function.c 11 May 2005 16:36:11 -0000 @@ -63,6 +63,7 @@ #include "integrate.h" #include "langhooks.h" #include "target.h" +#include "protector.h" #ifndef TRAMPOLINE_ALIGNMENT #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY @@ -155,6 +156,10 @@ /* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue in this function. */ static GTY(()) varray_type sibcall_epilogue; + +/* Current boundary mark for character arrays. */ +static int temp_boundary_mark = 0; + /* In order to evaluate some expressions, such as function calls returning structures in memory, we need to temporarily allocate stack locations. @@ -208,6 +213,8 @@ /* 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; }; /* This structure is used to record MEMs or pseudos used to replace VAR, any @@ -641,6 +648,7 @@ whose lifetime is controlled by CLEANUP_POINT_EXPRs. KEEP is 3 if we are to allocate something at an inner level to be treated as a variable in the block (e.g., a SAVE_EXPR). + KEEP is 5 if we allocate a place to return structure. TYPE is the type that will be used for the stack slot. */ @@ -651,6 +659,8 @@ unsigned int align; struct temp_slot *p, *best_p = 0; rtx slot; + int char_array = (flag_propolice_protection + && keep == 1 && search_string_def (type)); /* If SIZE is -1 it means that somebody tried to allocate a temporary of a variable size. */ @@ -676,7 +686,8 @@ && ! p->in_use && objects_must_conflict_p (p->type, type) && (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) { @@ -711,6 +722,7 @@ p->address = 0; p->rtl_expr = 0; p->type = best_p->type; + p->boundary_mark = best_p->boundary_mark; p->next = temp_slots; temp_slots = p; @@ -757,6 +769,16 @@ way the frame grows. We include the extra space if and only if it is above this slot. */ #ifdef FRAME_GROWS_DOWNWARD + /* The stack protector can share a character buffer with another buffer + in the different block only when the size of the first is bigger + than the second. p->size is used for this comparison. + But, in some situation, p->size is bigger than the actual size. + So, we should change p->size with its aligned size. */ + if (flag_propolice_protection + && char_array + && (frame_offset_old - frame_offset > + CEIL_ROUND (size, align / BITS_PER_UNIT))) + frame_offset_old = frame_offset + CEIL_ROUND (size, align / BITS_PER_UNIT); p->size = frame_offset_old - frame_offset; #else p->size = size; @@ -771,6 +793,7 @@ 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; } @@ -935,14 +958,16 @@ 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; @@ -3949,7 +3974,8 @@ 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 { @@ -6172,7 +6198,12 @@ /* Recreate the block tree from the note nesting. */ reorder_blocks_1 (get_insns (), block, &block_stack); - BLOCK_SUBBLOCKS (block) = blocks_nreverse (BLOCK_SUBBLOCKS (block)); + + /* In propolice-protection mode, disable to change the order of SUBBLOCKS + by the reason that the order is reversed from its + declaration sequence. */ + if (! flag_propolice_protection) + BLOCK_SUBBLOCKS (block) = blocks_nreverse (BLOCK_SUBBLOCKS (block)); /* Remove deleted blocks from the block fragment chains. */ reorder_fix_fragments (block);