This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: PATCH: better cpplex.c patch


Jeffrey A Law <law@cygnus.com> writes:

> The whole patch please -- including Makefile.in changes, the ChangeLog entry, etc.

2000-09-14  Greg McGary  <greg@mcgary.org>

include:
	* bounded-ptr.h: New file.

gcc:
	* Makefile.in (BOUNDED_PTR_H): New variable.
	(ggc-page.o, cpplex.o): Depend on $(BOUNDED_PTR_H).
	* cpplex.c (_cpp_expand_name_space): Use RELOCATE_POINTER_INCR_HIGH.
	(parse_number, parse_string, save_comment): Use SET_BOUNDS.
	* ggc-page.c (ggc_alloc): Use SET_BOUNDS.
	* ginclude/bounded-ptr.h: New file.


Index: gcc/Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.511
diff -u -p -r1.511 Makefile.in
--- Makefile.in	2000/09/11 01:50:45	1.511
+++ Makefile.in	2000/09/14 09:04:14
@@ -229,6 +229,7 @@ SYSTEM_HEADER_DIR = /usr/include
 # Where to find some libiberty headers.
 HASHTAB_H   = $(srcdir)/../include/hashtab.h
 OBSTACK_H   = $(srcdir)/../include/obstack.h
+BOUNDED_PTR_H = $(srcdir)/../include/bounded-ptr.h
 SPLAY_TREE_H= $(srcdir)/../include/splay-tree.h
 
 # Default cross SYSTEM_HEADER_DIR, to be overridden by targets.
@@ -1209,7 +1210,7 @@ ggc-simple.o: ggc-simple.c $(CONFIG_H) $
 	$(GGC_H) varray.h $(TIMEVAR_H)
 
 ggc-page.o: ggc-page.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h toplev.h \
-	$(GGC_H) varray.h $(TIMEVAR_H)
+	$(GGC_H) varray.h $(TIMEVAR_H) $(BOUNDED_PTR_H)
 
 ggc-none.o: ggc-none.c $(CONFIG_H) $(RTL_H) $(GGC_H)
 
@@ -1809,7 +1810,7 @@ cppmain.o:  cppmain.c  $(CONFIG_H) cppli
 
 cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
 cppexp.o:   cppexp.c   $(CONFIG_H) $(LIBCPP_DEPS) defaults.h
-cpplex.o:   cpplex.c   $(CONFIG_H) $(LIBCPP_DEPS)
+cpplex.o:   cpplex.c   $(CONFIG_H) $(LIBCPP_DEPS) $(BOUNDED_PTR_H)
 cppmacro.o: cppmacro.c $(CONFIG_H) $(LIBCPP_DEPS)
 cpplib.o:   cpplib.c   $(CONFIG_H) $(LIBCPP_DEPS) $(OBSTACK_H)
 cpphash.o:  cpphash.c  $(CONFIG_H) $(LIBCPP_DEPS) $(OBSTACK_H)
Index: gcc/cpplex.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cpplex.c,v
retrieving revision 1.95
diff -u -p -r1.95 cpplex.c
--- cpplex.c	2000/09/12 03:42:29	1.95
+++ cpplex.c	2000/09/14 09:04:16
@@ -44,6 +44,7 @@ o Correct pastability test for CPP_NAME 
 #include "cpplib.h"
 #include "cpphash.h"
 #include "symcat.h"
+#include "bounded-ptr.h"
 
 static const cpp_token placemarker_token = {0, 0, CPP_PLACEMARKER, 0 UNION_INIT_ZERO};
 static const cpp_token eof_token = {0, 0, CPP_EOF, 0 UNION_INIT_ZERO};
@@ -450,13 +451,19 @@ _cpp_expand_name_space (list, len)
   list->namebuf = (unsigned char *) xrealloc (list->namebuf, list->name_cap);
 
   /* Fix up token text pointers.  */
-  if (list->namebuf != old_namebuf)
+  if (list->namebuf != old_namebuf || __BOUNDED_POINTERS__)
     {
+      long disp = list->namebuf - old_namebuf;
       unsigned int i;
 
       for (i = 0; i < list->tokens_used; i++)
 	if (TOKEN_SPELL (&list->tokens[i]) == SPELL_STRING)
-	  list->tokens[i].val.str.text += (list->namebuf - old_namebuf);
+	  /* The token with zero length is the one on whose behalf
+	     we are expanding the namebuf, so be sure to increment
+	     its high bound to reflect the added space.  No other
+	     tokens should expand their high bounds.  */
+	  RELOCATE_POINTER_INCR_HIGH (list->tokens[i].val.str.text, disp,
+				      (list->tokens[i].val.str.len ? 0 : len));
     }
 }
 
@@ -1049,6 +1056,7 @@ parse_number (pfile, list, name)
  out:
   buffer->cur = cur;
   name->len = namebuf - name->text;
+  SET_BOUNDS (name->text, name->len);
   list->name_used = namebuf - list->namebuf;
 }
 
@@ -1199,6 +1207,7 @@ parse_string (pfile, list, token, termin
  out:
   buffer->cur = cur;
   name->len = namebuf - name->text;
+  SET_BOUNDS (name->text, name->len);
   list->name_used = namebuf - list->namebuf;
 
   if (null_count > 0)
@@ -1227,6 +1236,7 @@ save_comment (list, token, from, len, ty
     _cpp_expand_name_space (list, len);
 
   INIT_TOKEN_STR (list, token);
+  SET_BOUNDS (token->val.str.text, len);
   token->type = CPP_COMMENT;
   token->val.str.len = len;
 
Index: gcc/ggc-page.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ggc-page.c,v
retrieving revision 1.30
diff -u -p -r1.30 ggc-page.c
--- ggc-page.c	2000/08/29 20:57:11	1.30
+++ ggc-page.c	2000/09/14 09:04:17
@@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA.  */
 #include "flags.h"
 #include "ggc.h"
 #include "timevar.h"
+#include "bounded-ptr.h"
 
 #ifdef HAVE_MMAP_ANYWHERE
 #include <sys/mman.h>
@@ -725,6 +726,7 @@ ggc_alloc (size)
      the end.  */
   memset (result, 0xaf, 1 << order);
 #endif
+  SET_BOUNDS (result, size);
 
   /* Keep track of how many bytes are being allocated.  This
      information is used in deciding when to collect.  */
Index: include/bounded-ptr.h
===================================================================
RCS file: bounded-ptr.h
diff -N bounded-ptr.h
--- /dev/null	Tue May  5 13:32:27 1998
+++ bounded-ptr.h	Thu Sep 14 11:44:30 2000
@@ -0,0 +1,59 @@
+/* Header file for modules that link with gcc.c
+   Copyright (C) 2000 Free Software Foundation, Inc.
+   Contributed by Greg McGary <greg@mcgary.org>
+
+   This file is part of GNU CC.
+
+   GNU CC 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 2, or (at your option)
+   any later version.
+
+   GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _bounded_ptr_wrapper_h_
+#define _bounded_ptr_wrapper_h_
+
+#if __BOUNDED_POINTERS__
+/* Some crufty cpps choke on non-standard directives, even within the
+   untaken side of a conditional.  They can be foold by indenting '#'.  */
+ #include_next <bounded-ptr.h>
+#else
+
+/* Ensure that we can use __BOUNDED_POINTERS__ in C expressions.  */
+# undef __BOUNDED_POINTERS__
+# define __BOUNDED_POINTERS__ 0
+
+/* Do nothing if not compiling with -fbounded-pointers.  */
+
+# define BOUNDS_VIOLATED
+# define CHECK_BOUNDS_LOW(PTR) (PTR)
+# define CHECK_BOUNDS_HIGH(PTR) (PTR)
+# define CHECK_1(PTR) (PTR)
+# define CHECK_1_NULL_OK(PTR) (PTR)
+# define CHECK_N(ARG, N) (PTR)
+# define CHECK_N_NULL_OK(ARG, N) (PTR)
+# define CHECK_STRING(PTR) (PTR)
+# define CHECK_SIGSET(SET) (SET)
+# define CHECK_SIGSET_NULL_OK(SET) (SET)
+# define CHECK_IOCTL(ARG, CMD) (PTR)
+# define CHECK_FCNTL(ARG, CMD) (PTR)
+# define CHECK_N_PAGES(ARG, NBYTES) (PTR)
+# define SET_BOUNDS(PTR, N)
+# define BOUNDED_N(PTR, N) (PTR)
+# define BOUNDED_1(PTR) (PTR)
+# define RELOCATE_POINTER(PTR, DISP) ((PTR) += (DISP))
+# define RELOCATE_POINTER_INCR_HIGH(PTR, DISP, INCR) ((PTR) += (DISP))
+# define RELOCATE_POINTER_SET_HIGH(PTR, DISP, LENGTH) ((PTR) += (DISP))
+
+#endif /* __BOUNDED_POINTERS__ */
+
+#endif /* _bounded_ptr_wrapper_h_ */
Index: gcc/ginclude/bounded-ptr.h
===================================================================
RCS file: bounded-ptr.h
diff -N bounded-ptr.h
--- /dev/null	Tue May  5 13:32:27 1998
+++ bounded-ptr.h	Thu Sep 14 11:44:30 2000
@@ -0,0 +1,160 @@
+/* Header file for modules that link with gcc.c
+   Copyright (C) 2000 Free Software Foundation, Inc.
+   Contributed by Greg McGary <greg@mcgary.org>
+
+   This file is part of GNU CC.
+
+   GNU CC 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 2, or (at your option)
+   any later version.
+
+   GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _bounded_ptr_h_
+#define _bounded_ptr_h_
+
+#if __BOUNDED_POINTERS__
+
+# define BOUNDS_VIOLATED (__builtin_trap (), 0)
+
+/* Verify that pointer's value >= low.  Return pointer value.  */
+# define CHECK_BOUNDS_LOW(PTR)					\
+  (((__ptrvalue (PTR) < __ptrlow (PTR)) && BOUNDS_VIOLATED),	\
+   __ptrvalue (PTR))
+
+/* Verify that pointer's value < high.  Return pointer value.  */
+# define CHECK_BOUNDS_HIGH(PTR)					\
+  (((__ptrvalue (PTR) > __ptrhigh (PTR)) && BOUNDS_VIOLATED),	\
+   __ptrvalue (PTR))
+
+/* Check both bounds if COND is nonzero.  Return pointer value.  */
+# define _CHECK_N(PTR, N, COND)				\
+  (((COND)						\
+    && (__ptrvalue (PTR) < __ptrlow (PTR)		\
+	|| __ptrvalue (PTR) + (N) > __ptrhigh (PTR))	\
+    && BOUNDS_VIOLATED),				\
+   __ptrvalue (PTR))
+
+/* This is provided by the bounded-pointer version of glibc.  */
+extern void *__unbounded __ubp_memchr (const void *__unbounded, int, unsigned);
+
+/* Verify that a NUL-terminator occurs within the bounds of the string.  */
+# define _CHECK_STRING(PTR, COND)					\
+  (((COND)								\
+    && (__ptrvalue (PTR) < __ptrlow (PTR)				\
+	|| !__ubp_memchr (__ptrvalue (PTR), '\0',			\
+			  (__ptrhigh (PTR) - __ptrvalue (PTR))))	\
+    && BOUNDS_VIOLATED),						\
+   __ptrvalue (PTR))
+
+/* Check bounds of a pointer seated to an array of N objects.  */
+# define CHECK_N(PTR, N) _CHECK_N ((PTR), (N), 1)
+/* Same as CHECK_N, but tolerate PTR == NULL.  */
+# define CHECK_N_NULL_OK(PTR, N) _CHECK_N ((PTR), (N), __ptrvalue (PTR))
+
+/* Check for NUL-terminator within string's bounds.  */
+# define CHECK_STRING(PTR) _CHECK_STRING ((PTR), 1)
+/* Same as CHECK_STRING, but tolerate PTR == NULL.  */
+# define CHECK_STRING_NULL_OK(PTR) _CHECK_STRING ((PTR), __ptrvalue (PTR))
+
+/* Set the bounds of a bounded pointer so that it satisfies CHECK_N (PTR, N).  */
+# define SET_BOUNDS(PTR, N)							\
+  (__ptrlow (PTR) = __ptrvalue (PTR), __ptrhigh (PTR) = __ptrvalue (PTR) + (N))
+
+/* Return a bounded pointer with value PTR that satisfies CHECK_N (PTR, N).  */
+# define BOUNDED_N(PTR, N) 				\
+  ({ __typeof (PTR) __bounded _p_;			\
+     __ptrvalue _p_ = __ptrlow _p_ = __ptrvalue (PTR);	\
+     __ptrhigh _p_ = __ptrvalue _p_ + (N);		\
+     _p_; })
+
+/* When a buffer is expanded with realloc, and there are other pointers
+   into the old buffer, they must be relocated to the new buffer.  */
+
+/* Relocate the pointer and leave the width of its bounds unchanged.  */
+# define RELOCATE_POINTER(PTR, DISP) RELOCATE_POINTER_INCR_HIGH ((PTR), (DISP), 0)
+
+/* Relocate the pointer and increment the width of its bounds.  */
+# define RELOCATE_POINTER_INCR_HIGH(PTR, DISP, INCR)			\
+  (__ptrlow (PTR) += (DISP), __ptrhigh (PTR) += ((DISP) + (INCR)),	\
+   __ptrvalue (PTR) += (DISP))
+
+/* Relocate the pointer and reset the width of its bounds.  */
+# define RELOCATE_POINTER_SET_HIGH(PTR, DISP, LENGTH)				\
+  (__ptrlow (PTR) += (DISP), __ptrhigh (PTR) = (__ptrlow (PTR) + (LENGTH)),	\
+   __ptrvalue (PTR) += (DISP))
+
+/* Check bounds of signal syscall args with type sigset_t.  */
+# define CHECK_SIGSET(SET) CHECK_N ((SET), _NSIG / (8 * sizeof *(SET)))
+/* Same as CHECK_SIGSET, but tolerate SET == NULL.  */
+# define CHECK_SIGSET_NULL_OK(SET) CHECK_N_NULL_OK ((SET), _NSIG / (8 * sizeof *(SET)))
+
+# if defined (_IOC_SIZESHIFT) && defined (_IOC_SIZEBITS)
+/* Extract the size of the ioctl data and check its bounds.  */
+#  define CHECK_IOCTL(PTR, CMD)						\
+  CHECK_N ((const char *) (PTR),					\
+	   (((CMD) >> _IOC_SIZESHIFT) & ((1 << _IOC_SIZEBITS) - 1)))
+# else
+/* We don't know the size of the ioctl data, so the best we can do
+   is check that the first byte is within bounds.  */
+#  define CHECK_IOCTL(PTR, CMD) CHECK_1 ((const char *) PTR)
+# endif
+
+/* Check bounds of `struct flock *' for the locking fcntl commands.  */
+# define CHECK_FCNTL(PTR, CMD)					\
+  (((CMD) == F_GETLK || (CMD) == F_SETLK || (CMD) == F_SETLKW)	\
+   ? CHECK_1 ((struct flock *) PTR) : (unsigned long) (PTR))
+
+# define CHECK_N_PAGES(PTR, NBYTES)					\
+  ({ int _page_size_ = sysconf (_SC_PAGE_SIZE);				\
+     CHECK_N ((PTR), ((NBYTES) + _page_size_ - 1) / _page_size_); })
+
+#else /* !__BOUNDED_POINTERS__ */
+
+/* Ensure that we can use __BOUNDED_POINTERS__ in C expressions.  */
+# undef __BOUNDED_POINTERS__
+# define __BOUNDED_POINTERS__ 0
+
+/* Do nothing if not compiling with -fbounded-pointers.  */
+
+# define BOUNDS_VIOLATED
+# define CHECK_BOUNDS_LOW(PTR) (PTR)
+# define CHECK_BOUNDS_HIGH(PTR) (PTR)
+# define CHECK_N(PTR, N) (PTR)
+# define CHECK_N_NULL_OK(PTR, N) (PTR)
+# define CHECK_STRING(PTR) (PTR)
+
+# define SET_BOUNDS(PTR, N)
+# define BOUNDED_N(PTR, N) (PTR)
+
+# define RELOCATE_POINTER(PTR, DISP) ((PTR) += (DISP))
+# define RELOCATE_POINTER_INCR_HIGH(PTR, DISP, INCR) ((PTR) += (DISP))
+# define RELOCATE_POINTER_SET_HIGH(PTR, DISP, LENGTH) ((PTR) += (DISP))
+
+# define CHECK_SIGSET(SET) (SET)
+# define CHECK_SIGSET_NULL_OK(SET) (SET)
+# define CHECK_IOCTL(PTR, CMD) (PTR)
+# define CHECK_FCNTL(PTR, CMD) (PTR)
+# define CHECK_N_PAGES(PTR, NBYTES) (PTR)
+
+#endif /* !__BOUNDED_POINTERS__ */
+
+/* Some shorthand notations... */
+
+/* Return a bounded pointer with value PTR that satisfies CHECK_1 (PTR).  */
+#define BOUNDED_1(PTR) BOUNDED_N (PTR, 1)
+/* Check bounds of a pointer seated to a single object.  */
+# define CHECK_1(PTR) CHECK_N ((PTR), 1)
+/* Same as CHECK_1, but tolerate PTR == NULL.  */
+# define CHECK_1_NULL_OK(PTR) CHECK_N_NULL_OK ((PTR), 1)
+
+#endif /* _bounded_ptr_h_ */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]