]> granicus.if.org Git - gc/commitdiff
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>
Thu, 9 Feb 2017 22:08:42 +0000 (01:08 +0300)
(Cherry-pick commit 7f6b5de from 'release-7_4' branch.)

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).

* mark.c (GC_mark_from): Cast (sizeof(word)-1) to word before "~"
operation.
* 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 7d710e30f947d334c283de249fbf208b53935b8d..725c37d9daba992b4d514af35481e72ca9f65254 100644 (file)
@@ -879,7 +879,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 (limit > stack_top && base < GC_stackbottom) {
           /* Part of the stack; ignore it. */
index e6120b124dcb11e8772759c295839acdd65aacbc..7adbd04014dcc3425b38d9588738964117d62f9d 100644 (file)
@@ -695,8 +695,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 510834341e6788972757b8749b262138220c7422..37f7ddeee9034b4b469e8bed42275cf9b4f37da1 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -670,7 +670,7 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
 #           define SHARE_BYTES 2048
             if (descr > SHARE_BYTES && GC_parallel
                 && mark_stack_top < 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 = new_size + sizeof(word);
                                         /* makes sure we handle         */
index e48f6608ba92b5085ef976d7f95c262840b6a41f..bf8ffc6c35ceb0cae9aa9ea8cdbdfde978a682ff 100644 (file)
@@ -157,9 +157,9 @@ void GC_add_roots_inner(ptr_t b, ptr_t e, GC_bool tmp)
     struct roots * old;
 
     GC_ASSERT(b <= 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 (b >= e) return; /* nothing to do */
 
@@ -305,8 +305,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();
@@ -448,7 +448,7 @@ GC_API void GC_CALL GC_exclude_static_roots(void *b, void *e)
     DCL_LOCK_STATE;
 
     /* Adjust the upper boundary for safety (round down) */
-    e = (void *)((word)e & ~(sizeof(word) - 1));
+    e = (void *)((word)e & ~(word)(sizeof(word) - 1));
 
     if (b == e) return;  /* nothing to exclude? */
 
index b0b6a0f3f0edc21fbbc53a5c9f1b00014cae5404..779dd3e7047a8ed5ffdda80b8cb68af567fc0bef 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
@@ -536,7 +536,7 @@ GC_INNER char *GC_parse_map_entry(char *buf_ptr, ptr_t *start, ptr_t *end,
              /* 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());
@@ -575,7 +575,7 @@ GC_INNER char *GC_parse_map_entry(char *buf_ptr, ptr_t *start, ptr_t *end,
     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());
@@ -1855,7 +1855,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));
@@ -1899,7 +1899,7 @@ void GC_register_data_segments(void)
 ptr_t GC_FreeBSDGetDataStart(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       */
     volatile word next_page = (text_end + (word)max_page_size - 1)
                               & ~((word)max_page_size - 1);
@@ -2220,7 +2220,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 {
         /* VirtualProtect only works on regions returned by a   */
         /* single VirtualAlloc call.  Thus we allocate one      */
@@ -3753,7 +3753,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");