Fix '~' operator application to unsigned values shorter than word
authorIvan Maidanski <ivmai@mail.ru>
Wed, 7 Dec 2016 08:32:30 +0000 (11:32 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Wed, 7 Dec 2016 08:32:30 +0000 (11:32 +0300)
Without the fix, unsigned result of "~" operator is zero-extended
to a wide type (word) thus the result has leading zeros (which is
not expected to be).

* dyn_load.c [HAVE_DL_ITERATE_PHDR] (GC_register_dynlib_callback):
Cast (sizeof(word)-1) to word before "~" operation.
* mark.c (GC_mark_from): Likewise.
* mark_rts.c (GC_add_roots_inner, GC_exclude_static_roots): Likewise.
* mark_rts.c [!MSWIN32 && !MSWINCE && !CYGWIN32]
(GC_remove_roots_inner): Likewise.
* os_dep.c [SVR4 || AUX || DGUX || LINUX && SPARC]
(GC_SysVGetDataStart): Likewise.
* os_dep.c [!MSWIN32 && DATASTART_USES_BSDGETDATASTART]
(GC_FreeBSDGetDataStart): Likewise.
* dyn_load.c [(MSWIN32 || MSWINCE || CYGWIN32) && !GC_WIN32_THREADS]
(GC_cond_add_roots): Cast (dwAllocationGranularity-1) to word before
"~" operation.
* include/private/gc_priv.h (HBLKPTR): Cast (HBLKSIZE-1) to word
before "~" operation.
* os_dep.c [USE_WINALLOC || CYGWIN32] (GC_win32_get_mem): Likewise.
* mark.c (GC_mark_from): Change type of new_size local variable from
int to word.
* os_dep.c [OPENBSD] (GC_find_limit_openbsd, GC_skip_hole_openbsd):
Change type of pgsz local variable from size_t to word (to avoid
implicit unsigned value extension after "~" operation).
* os_dep.c [PROC_VDB] (GC_read_dirty): Cast (sizeof(long)-1) to word
before "~" operation.

dyn_load.c
include/private/gc_priv.h
mark.c
mark_rts.c
os_dep.c

index 42534c1..d6616a5 100644 (file)
@@ -485,8 +485,8 @@ STATIC int GC_register_dynlib_callback(struct dl_phdr_info * info,
           /* rounding to the next multiple of ALIGNMENT, so, most   */
           /* probably, we should remove the corresponding assertion */
           /* check in GC_add_roots_inner along with this code line. */
-          /* start pointer value may require aligning */
-          start = (ptr_t)((word)start & ~(sizeof(word) - 1));
+          /* start pointer value may require aligning.              */
+          start = (ptr_t)((word)start & ~(word)(sizeof(word) - 1));
 #       endif
         if (n_load_segs >= MAX_LOAD_SEGS) {
           if (!load_segs_overflow) {
@@ -926,7 +926,7 @@ GC_INNER void GC_register_dynamic_libraries(void)
 #   else
       char * stack_top
          = (char *)((word)GC_approx_sp() &
-                        ~(GC_sysinfo.dwAllocationGranularity - 1));
+                    ~(word)(GC_sysinfo.dwAllocationGranularity - 1));
 
       if (base == limit) return;
       if ((word)limit > (word)stack_top
index 218ca72..0888be7 100644 (file)
@@ -819,8 +819,8 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc;
 
 # define modHBLKSZ(n) ((n) & (HBLKSIZE-1))
 
-# define HBLKPTR(objptr) ((struct hblk *)(((word) (objptr)) & ~(HBLKSIZE-1)))
-
+# define HBLKPTR(objptr) ((struct hblk *)(((word)(objptr)) \
+                                          & ~(word)(HBLKSIZE-1)))
 # define HBLKDISPL(objptr) (((size_t) (objptr)) & (HBLKSIZE-1))
 
 /* Round up allocation size (in bytes) to a multiple of a granule.      */
diff --git a/mark.c b/mark.c
index 0e8991c..8b776f5 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -660,7 +660,8 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
 #           define SHARE_BYTES 2048
             if (descr > SHARE_BYTES && GC_parallel
                 && (word)mark_stack_top < (word)(mark_stack_limit - 1)) {
-              int new_size = (descr/2) & ~(sizeof(word)-1);
+              word new_size = (descr/2) & ~(word)(sizeof(word)-1);
+
               mark_stack_top -> mse_start = current_p;
               mark_stack_top -> mse_descr.w = new_size + sizeof(word);
                                         /* makes sure we handle         */
index d0d2ba4..067e86d 100644 (file)
@@ -169,9 +169,9 @@ GC_API void GC_CALL GC_add_roots(void *b, void *e)
 void GC_add_roots_inner(ptr_t b, ptr_t e, GC_bool tmp)
 {
     GC_ASSERT((word)b <= (word)e);
-    b = (ptr_t)(((word)b + (sizeof(word) - 1)) & ~(sizeof(word) - 1));
+    b = (ptr_t)(((word)b + (sizeof(word) - 1)) & ~(word)(sizeof(word) - 1));
                                         /* round b up to word boundary */
-    e = (ptr_t)((word)e & ~(sizeof(word) - 1));
+    e = (ptr_t)((word)e & ~(word)(sizeof(word) - 1));
                                         /* round e down to word boundary */
     if ((word)b >= (word)e) return; /* nothing to do */
 
@@ -339,8 +339,8 @@ STATIC void GC_remove_tmp_roots(void)
     DCL_LOCK_STATE;
 
     /* Quick check whether has nothing to do */
-    if ((((word)b + (sizeof(word) - 1)) & ~(sizeof(word) - 1)) >=
-        ((word)e & ~(sizeof(word) - 1)))
+    if ((((word)b + (sizeof(word) - 1)) & ~(word)(sizeof(word) - 1)) >=
+        ((word)e & ~(word)(sizeof(word) - 1)))
       return;
 
     LOCK();
@@ -487,9 +487,10 @@ GC_API void GC_CALL GC_exclude_static_roots(void *b, void *e)
     if (b == e) return;  /* nothing to exclude? */
 
     /* Round boundaries (in direction reverse to that of GC_add_roots). */
-    b = (void *)((word)b & ~(sizeof(word) - 1));
-    e = (void *)(((word)e + (sizeof(word) - 1)) & ~(sizeof(word) - 1));
-    if (0 == e) e = (void *)(word)(~(sizeof(word) - 1)); /* handle overflow */
+    b = (void *)((word)b & ~(word)(sizeof(word) - 1));
+    e = (void *)(((word)e + (sizeof(word) - 1)) & ~(word)(sizeof(word) - 1));
+    if (NULL == e)
+      e = (void *)(~(word)(sizeof(word) - 1)); /* handle overflow */
 
     LOCK();
     GC_exclude_static_roots_inner(b, e);
index 3a65074..0c43ca7 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
@@ -544,7 +544,7 @@ GC_INNER char * GC_get_maps(void)
              /* allocation lock held.                           */
 
     struct sigaction act;
-    size_t pgsz = (size_t)sysconf(_SC_PAGESIZE);
+    word pgsz = (word)sysconf(_SC_PAGESIZE);
 
     GC_ASSERT((word)bound >= pgsz);
     GC_ASSERT(I_HOLD_LOCK());
@@ -584,7 +584,7 @@ GC_INNER char * GC_get_maps(void)
     static volatile int firstpass;
 
     struct sigaction act;
-    size_t pgsz = (size_t)sysconf(_SC_PAGESIZE);
+    word pgsz = (word)sysconf(_SC_PAGESIZE);
 
     GC_ASSERT((word)bound >= pgsz);
     GC_ASSERT(I_HOLD_LOCK());
@@ -1860,7 +1860,7 @@ void GC_register_data_segments(void)
   ptr_t GC_SysVGetDataStart(size_t max_page_size, ptr_t etext_addr)
   {
     word text_end = ((word)(etext_addr) + sizeof(word) - 1)
-                    & ~(sizeof(word) - 1);
+                    & ~(word)(sizeof(word) - 1);
         /* etext rounded to word boundary       */
     word next_page = ((text_end + (word)max_page_size - 1)
                       & ~((word)max_page_size - 1));
@@ -1907,7 +1907,7 @@ void GC_register_data_segments(void)
                                         ptr_t etext_addr)
   {
     word text_end = ((word)(etext_addr) + sizeof(word) - 1)
-                     & ~(sizeof(word) - 1);
+                     & ~(word)(sizeof(word) - 1);
         /* etext rounded to word boundary       */
     volatile word next_page = (text_end + (word)max_page_size - 1)
                               & ~((word)max_page_size - 1);
@@ -2307,7 +2307,7 @@ void * os2_alloc(size_t bytes)
         /* There are also unconfirmed rumors of other           */
         /* problems, so we dodge the issue.                     */
         result = (ptr_t)(((word)GlobalAlloc(0, SIZET_SAT_ADD(bytes, HBLKSIZE))
-                            + HBLKSIZE - 1) & ~(HBLKSIZE - 1));
+                            + HBLKSIZE - 1) & ~(word)(HBLKSIZE - 1));
       } else
 #   endif
     /* else */ {
@@ -3679,7 +3679,8 @@ GC_INNER void GC_read_dirty(void)
                 }
             }
         }
-        bufp = (char *)(((word)bufp + (sizeof(long)-1)) & ~(sizeof(long)-1));
+        bufp = (char *)(((word)bufp + (sizeof(long)-1))
+                        & ~(word)(sizeof(long)-1));
     }
 #   ifdef DEBUG_DIRTY_BITS
       GC_log_printf("Proc VDB read done\n");