From 4338bb085a471f3cf7fbe53c564082a200d3aa3c Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Wed, 7 Dec 2016 11:32:30 +0300 Subject: [PATCH] Fix '~' operator application to unsigned values shorter than word 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 | 6 +++--- include/private/gc_priv.h | 4 ++-- mark.c | 3 ++- mark_rts.c | 15 ++++++++------- os_dep.c | 13 +++++++------ 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/dyn_load.c b/dyn_load.c index 42534c1..d6616a5 100644 --- a/dyn_load.c +++ b/dyn_load.c @@ -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 diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 218ca72..0888be7 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -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 --- 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 */ diff --git a/mark_rts.c b/mark_rts.c index d0d2ba4..067e86d 100644 --- a/mark_rts.c +++ b/mark_rts.c @@ -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); diff --git a/os_dep.c b/os_dep.c index 3a65074..0c43ca7 100644 --- 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"); -- 2.7.4