This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix memory overflow in mainline (take 2)
- From: Roger Sayle <roger at www dot eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Henderson <rth at redhat dot com>, Jan Hubicka <jh at suse dot cz>
- Date: Mon, 17 Feb 2003 09:42:05 -0700 (MST)
- Subject: [PATCH] Fix memory overflow in mainline (take 2)
On Mon, 17 Feb 2003, Jan Hubicka wrote:
> > Jan Hubicka wrote:
> > > I will install this as obvious once machines start up.
> > >
> > > Mon Feb 17 13:45:52 CET 2003 Jan Hubicka <jh@suse.cz>
> > > * recog.c (split_all_insns): Fix memory overflow.
> >
> > A good try but this is wrong. sbitmap_copy will copy the
> > number of bits in the destination, as the source has less
> > words this will again read beyond the end of the blocks array.
> >
> > What we really need is an sbitmap_resize. If this function
> > also takes an argument that specifies the initial value of
> > the new bits, it'll also avoid the loop immediately following
> > in split_all_insns which sets them individually.
>
> Alternativly the whole thing can be reorganized to simply use
> dirty flags of BBs...
> I don't have time to do that right now, unfortunately...
I'm currently boostrapping and regression testing the following
patch. Unfortunately, Jan's fix simply changes the failure mode
from a write past the end of an array, into a read from past the
end of an array.
The new sbitmap_resize function should also be useful elsewhere,
such as SSA, GCSE etc...
Ok for mainline it passes bootstrap and regression testing?
2003-02-17 Roger Sayle <roger@eyesopen.com>
* sbitmap.c (sbitmap_resize): New function.
* sbitmap.h (sbitmap_resize): Prototype here.
* recog.c (split_all_insns): Use sbitmap_resize.
Index: sbitmap.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sbitmap.c,v
retrieving revision 1.24
diff -c -3 -p -r1.24 sbitmap.c
*** sbitmap.c 16 Dec 2002 18:19:54 -0000 1.24
--- sbitmap.c 17 Feb 2003 17:08:43 -0000
***************
*** 1,5 ****
/* Simple bitmaps.
! Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
This file is part of GCC.
--- 1,5 ----
/* Simple bitmaps.
! Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
*************** sbitmap_alloc (n_elms)
*** 43,48 ****
--- 43,106 ----
amt = (sizeof (struct simple_bitmap_def)
+ bytes - sizeof (SBITMAP_ELT_TYPE));
bmap = (sbitmap) xmalloc (amt);
+ bmap->n_bits = n_elms;
+ bmap->size = size;
+ bmap->bytes = bytes;
+ return bmap;
+ }
+
+ /* Resize a simple bitmap BMAP to N_ELMS bits. If increasing the
+ size of BMAP, clear the new bits to zero if the DEF argument
+ is zero, and set them to one otherwise. */
+
+ sbitmap
+ sbitmap_resize (bmap, n_elms, def)
+ sbitmap bmap;
+ unsigned int n_elms;
+ int def;
+ {
+ unsigned int bytes, size, amt;
+ unsigned int last_bit;
+
+ size = SBITMAP_SET_SIZE (n_elms);
+ bytes = size * sizeof (SBITMAP_ELT_TYPE);
+ if (bytes > bmap->bytes)
+ {
+ amt = (sizeof (struct simple_bitmap_def)
+ + bytes - sizeof (SBITMAP_ELT_TYPE));
+ bmap = (sbitmap) xrealloc ((PTR) bmap, amt);
+ }
+
+ if (n_elms > bmap->n_bits)
+ {
+ if (def)
+ {
+ memset ((PTR) (bmap->elms + bmap->size), -1, bytes - bmap->bytes);
+
+ /* Set the new bits if the original last element. */
+ last_bit = bmap->n_bits % SBITMAP_ELT_BITS;
+ if (last_bit)
+ bmap->elms[bmap->size - 1]
+ |= ~((SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit));
+
+ /* Clear the unused bit in the new last element. */
+ last_bit = n_elms % SBITMAP_ELT_BITS;
+ if (last_bit)
+ bmap->elms[size - 1]
+ &= (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
+ }
+ else
+ memset ((PTR) (bmap->elms + bmap->size), 0, bytes - bmap->bytes);
+ }
+ else if (n_elms < bmap->n_bits)
+ {
+ /* Clear the surplus bits in the last word. */
+ last_bit = n_elms % SBITMAP_ELT_BITS;
+ if (last_bit)
+ bmap->elms[size - 1]
+ &= (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
+ }
+
bmap->n_bits = n_elms;
bmap->size = size;
bmap->bytes = bytes;
Index: sbitmap.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sbitmap.h,v
retrieving revision 1.18
diff -c -3 -p -r1.18 sbitmap.h
*** sbitmap.h 15 Jul 2002 14:07:05 -0000 1.18
--- sbitmap.h 17 Feb 2003 17:08:43 -0000
***************
*** 1,5 ****
/* Simple bitmaps.
! Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
This file is part of GCC.
--- 1,5 ----
/* Simple bitmaps.
! Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
*************** extern void dump_sbitmap_vector PARAMS
*** 125,130 ****
--- 125,131 ----
int));
extern sbitmap sbitmap_alloc PARAMS ((unsigned int));
extern sbitmap *sbitmap_vector_alloc PARAMS ((unsigned int, unsigned int));
+ extern sbitmap sbitmap_resize PARAMS ((sbitmap, unsigned int, int));
extern void sbitmap_copy PARAMS ((sbitmap, sbitmap));
extern int sbitmap_equal PARAMS ((sbitmap, sbitmap));
extern void sbitmap_zero PARAMS ((sbitmap));
Index: recog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/recog.c,v
retrieving revision 1.176
diff -c -3 -p -r1.176 recog.c
*** recog.c 17 Feb 2003 15:21:32 -0000 1.176
--- recog.c 17 Feb 2003 17:08:43 -0000
*************** split_all_insns (upd_life)
*** 2883,2900 ****
find_many_sub_basic_blocks (blocks);
if (old_last_basic_block != last_basic_block && upd_life)
! {
! sbitmap new_blocks = sbitmap_alloc (last_basic_block);
!
! sbitmap_copy (new_blocks, blocks);
! while (old_last_basic_block < last_basic_block)
! {
! SET_BIT (new_blocks, old_last_basic_block);
! old_last_basic_block++;
! }
! sbitmap_free (blocks);
! new_blocks = blocks;
! }
}
if (changed && upd_life)
--- 2883,2889 ----
find_many_sub_basic_blocks (blocks);
if (old_last_basic_block != last_basic_block && upd_life)
! blocks = sbitmap_resize (blocks, last_basic_block, 1);
}
if (changed && upd_life)
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833