diff --git a/racket/src/configure b/racket/src/configure index cd2a2e7f1d..6f66522ed4 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -827,6 +827,7 @@ enable_ffipoll enable_gprof enable_gcov enable_noopt +enable_ubsan ' ac_precious_vars='build_alias host_alias @@ -1481,6 +1482,7 @@ Optional Features: --enable-gcov compile to gather gcov statistics (gcc3 only) --enable-strip strip debug on install (usually enabled by default) --enable-noopt drop -O C flags (useful for low-level debugging) + --enable-ubsan compile with -fsanitize=undefined) Some influential environment variables: CC C compiler command @@ -2824,6 +2826,11 @@ if test "${enable_noopt+set}" = set; then : enableval=$enable_noopt; fi +# Check whether --enable-ubsan was given. +if test "${enable_ubsan+set}" = set; then : + enableval=$enable_ubsan; +fi + ###### Some flags imply other flags ####### @@ -6791,6 +6798,16 @@ if test "${enable_noopt}" = "yes" ; then PREFLAGS=`echo "$PREFLAGS" | awk "$AWKPRG"` fi +############## ubsan ################ + +if test "${enable_ubsan}" = "yes" ; then + UBSAN="-fsanitize=undefined -fno-sanitize=alignment -fno-sanitize=float-divide-by-zero" + CFLAGS="$CFLAGS $UBSAN" + CPPFLAGS="$CPPFLAGS $UBSAN" + PREFLAGS="$PREFLAGS $UBSAN" + LDFLAGS="$LDFLAGS $UBSAN" +fi + ############## usersetup ################ if test "${enable_usersetup}" != "yes" ; then diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index 5a4267f531..b079501037 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -86,6 +86,7 @@ AC_ARG_ENABLE(gcov, [ --enable-gcov compile to gather gcov statist AC_ARG_ENABLE(noopt, [ --enable-strip strip debug on install (usually enabled by default)]) AC_ARG_ENABLE(noopt, [ --enable-noopt drop -O C flags (useful for low-level debugging)]) +AC_ARG_ENABLE(ubsan, [ --enable-ubsan compile with -fsanitize=undefined)]) ###### Some flags imply other flags ####### @@ -1629,6 +1630,16 @@ if test "${enable_noopt}" = "yes" ; then PREFLAGS=`echo "$PREFLAGS" | awk "$AWKPRG"` fi +############## ubsan ################ + +if test "${enable_ubsan}" = "yes" ; then + UBSAN="-fsanitize=undefined -fno-sanitize=alignment -fno-sanitize=float-divide-by-zero" + CFLAGS="$CFLAGS $UBSAN" + CPPFLAGS="$CPPFLAGS $UBSAN" + PREFLAGS="$PREFLAGS $UBSAN" + LDFLAGS="$LDFLAGS $UBSAN" +fi + ############## usersetup ################ if test "${enable_usersetup}" != "yes" ; then diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index 4aadc9f450..a06ea84c29 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -136,7 +136,8 @@ inline static int create_blank_owner_set(NewGC *gc) gc->owner_table_size = curr_size; naya = (OTEntry **)ofm_malloc(curr_size * sizeof(OTEntry*)); - memcpy(naya, owner_table, old_size*sizeof(OTEntry*)); + if (old_size) + memcpy(naya, owner_table, old_size*sizeof(OTEntry*)); gc->owner_table = owner_table = naya; bzero(((char*)owner_table) + (sizeof(OTEntry*) * old_size), (curr_size - old_size) * sizeof(OTEntry*)); diff --git a/racket/src/racket/gc2/roots.c b/racket/src/racket/gc2/roots.c index 1b87cb53fc..fddd5afa7a 100644 --- a/racket/src/racket/gc2/roots.c +++ b/racket/src/racket/gc2/roots.c @@ -17,7 +17,8 @@ static void grow_roots(Roots *roots) { roots->size = roots->size ? ( 2 * roots->size ) : 500; new_roots = (uintptr_t *)ofm_malloc(sizeof(uintptr_t) * (roots->size + 1)); - memcpy((void *)new_roots, (void *)roots->roots, sizeof(uintptr_t) * roots->count); + if (roots->count) + memcpy((void *)new_roots, (void *)roots->roots, sizeof(uintptr_t) * roots->count); if (roots->roots) free(roots->roots); diff --git a/racket/src/racket/gc2/vm_osx.c b/racket/src/racket/gc2/vm_osx.c index 00dbc5ecc5..a9b895482a 100644 --- a/racket/src/racket/gc2/vm_osx.c +++ b/racket/src/racket/gc2/vm_osx.c @@ -362,6 +362,10 @@ void exception_thread(void *shared_thread_state) /* block until we get an exception message */ retval = mach_msg(message, MACH_RCV_MSG, 0, sizeof(mach_exc_msg_t), exc_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + if(retval != KERN_SUCCESS) { + GCPRINT(GCOUTF, "Message receive failed: %s\n", mach_error_string(retval)); + abort(); + } /* forward off the handling of this message */ if(!exc_server(message, reply)) { GCPRINT(GCOUTF, "INTERNAL ERROR: exc_server() didn't like something\n"); @@ -370,6 +374,10 @@ void exception_thread(void *shared_thread_state) /* send the message back out to the thread */ retval = mach_msg(reply, MACH_SEND_MSG, sizeof(mach_reply_msg_t), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + if(retval != KERN_SUCCESS) { + GCPRINT(GCOUTF, "Message send failed: %s\n", mach_error_string(retval)); + abort(); + } } } diff --git a/racket/src/racket/sgc/sgc.c b/racket/src/racket/sgc/sgc.c index 54cf39106e..14286b9fe4 100644 --- a/racket/src/racket/sgc/sgc.c +++ b/racket/src/racket/sgc/sgc.c @@ -1372,7 +1372,8 @@ static void *realloc_collect_temp(void *v, intptr_t oldsize, intptr_t newsize) void *naya; naya = platform_plain_sector((newsize + SECTOR_SEGMENT_SIZE - 1) >> LOG_SECTOR_SEGMENT_SIZE, 0); - memcpy(naya, v, oldsize); + if (oldsize) + memcpy(naya, v, oldsize); if (v) munmap(v, (oldsize + SECTOR_SEGMENT_SIZE - 1) >> LOG_SECTOR_SEGMENT_SIZE); diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index 50eb3befe2..c704dd809d 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -1125,7 +1125,8 @@ void scheme_new_mark_segment(Scheme_Thread *p) seg = scheme_malloc_allow_interior(sizeof(Scheme_Cont_Mark) * SCHEME_MARK_SEGMENT_SIZE); segs[c] = seg; - memcpy(segs, p->cont_mark_stack_segments, c * sizeof(Scheme_Cont_Mark *)); + if (c) + memcpy(segs, p->cont_mark_stack_segments, c * sizeof(Scheme_Cont_Mark *)); p->cont_mark_seg_count++; p->cont_mark_stack_segments = segs; diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 7e160f7fb6..bf8589cd2a 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -5308,7 +5308,8 @@ static Scheme_Meta_Continuation *clone_meta_cont(Scheme_Meta_Continuation *mc, } else { Scheme_Cont_Mark *cp; cp = MALLOC_N(Scheme_Cont_Mark, naya->cont_mark_total); - memcpy(cp, mc->cont_mark_stack_copied, naya->cont_mark_total * sizeof(Scheme_Cont_Mark)); + if (naya->cont_mark_total) + memcpy(cp, mc->cont_mark_stack_copied, naya->cont_mark_total * sizeof(Scheme_Cont_Mark)); clear_cm_copy_caches(cp, naya->cont_mark_total); naya->cont_mark_stack_copied = cp; naya->cm_caches = 0; diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index 155cb894f6..ef8ff5ff55 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -1248,7 +1248,7 @@ int scheme_generate_flonum_local_unboxing(mz_jit_state *jitter, int push, int no /*========================================================================*/ #ifdef JIT_PRECISE_GC -static Scheme_Object example_so = { scheme_native_closure_type, 0 }; +static struct { Scheme_Object so; int filler; } example_so = { { scheme_native_closure_type, 0}, 0 }; #endif static Scheme_Native_Lambda *create_native_lambda(Scheme_Lambda *lam, int clear_code_after_jit, diff --git a/racket/src/racket/src/marshal.c b/racket/src/racket/src/marshal.c index 09c67b2fd1..e09faf5aee 100644 --- a/racket/src/racket/src/marshal.c +++ b/racket/src/racket/src/marshal.c @@ -852,7 +852,8 @@ static Scheme_Object *write_lambda(Scheme_Object *obj) /* Need to grow the array */ Scheme_Object **a; a = MALLOC_N(Scheme_Object *, (pos ? 2 * pos : 32)); - memcpy(a, mt->cdata_map, pos * sizeof(Scheme_Object *)); + if (pos) + memcpy(a, mt->cdata_map, pos * sizeof(Scheme_Object *)); mt->cdata_map = a; } mt->cdata_counter++; diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index 7dc9bbcac7..45777169c2 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -2677,7 +2677,8 @@ static void register_local_argument_types(Scheme_App_Rec *app, Scheme_App2_Rec * } else if (predicate_implies(lam->ir_info->arg_types[i], pred)) { /* widen */ lam->ir_info->arg_types[i] = pred; - lam->ir_info->arg_type_contributors[i] |= (1 << (nth_app-1)); + if (nth_app) + lam->ir_info->arg_type_contributors[i] |= (1 << (nth_app-1)); } else widen_to_top = 1; } else diff --git a/racket/src/racket/src/portfun.c b/racket/src/racket/src/portfun.c index cadf4ee4cd..d0a8966d0d 100644 --- a/racket/src/racket/src/portfun.c +++ b/racket/src/racket/src/portfun.c @@ -665,7 +665,8 @@ string_write_bytes(Scheme_Output_Port *port, memcpy(is->string, old, is->index); } - memcpy(is->string + is->index, str + d, len); + if (len) + memcpy(is->string + is->index, str + d, len); is->index += len; return len; diff --git a/racket/src/racket/src/print.c b/racket/src/racket/src/print.c index add80b650b..6b7ce16273 100644 --- a/racket/src/racket/src/print.c +++ b/racket/src/racket/src/print.c @@ -1235,7 +1235,8 @@ static void print_this_string(PrintParams *pp, const char *str, int offset, int memcpy(pp->print_buffer, oldstr, pp->print_position); } - memcpy(pp->print_buffer + pp->print_position, str + offset, len); + if (len) + memcpy(pp->print_buffer + pp->print_position, str + offset, len); pp->print_position += len; pp->print_offset += len; @@ -4144,7 +4145,8 @@ void scheme_set_type_printer(Scheme_Type stype, Scheme_Type_Printer printer) Scheme_Type_Printer *naya; naya = MALLOC_N(Scheme_Type_Printer, stype + 10); memset(naya, 0, sizeof(Scheme_Type_Printer) * (stype + 10)); - memcpy(naya, printers, sizeof(Scheme_Type_Printer) * printers_count); + if (printers_count) + memcpy(naya, printers, sizeof(Scheme_Type_Printer) * printers_count); printers_count = stype + 10; printers = naya; } diff --git a/racket/src/racket/src/regexp.c b/racket/src/racket/src/regexp.c index c5be06ac53..6166ee4f4f 100644 --- a/racket/src/racket/src/regexp.c +++ b/racket/src/racket/src/regexp.c @@ -2448,7 +2448,8 @@ static void stack_room(Regwork *rw, int amt) sz = rw->rewind_stack_size * 2; if (!sz) sz = MATCH_STACK_SIZE; p = (rxpos *)scheme_malloc_atomic(sizeof(rxpos)*sz); - memcpy(p, rw->rewind_stack, rw->rewind_stack_size * sizeof(rxpos)); + if (rw->rewind_stack_size) + memcpy(p, rw->rewind_stack, rw->rewind_stack_size * sizeof(rxpos)); rw->rewind_stack = p; rw->rewind_stack_size = sz; } @@ -2964,7 +2965,8 @@ static void read_more_from_lazy_string(Regwork *rw, rxpos need_total) 0 /* not UTF-16 */); tlen = blen + ls->blen; s = (char *)scheme_malloc_atomic(tlen); - memcpy(s, ls->s, ls->blen); + if (ls->blen) + memcpy(s, ls->s, ls->blen); scheme_utf8_encode(ls->chars, ls->start + ls->done, ls->start + ls->done + amt, (unsigned char *)s, ls->blen, 0 /* not UTF-16 */); @@ -3012,7 +3014,8 @@ static void read_more_from_regport(Regwork *rw, rxpos need_total) size = 16; naya = (char *)scheme_malloc_atomic(size); - memcpy(naya, rw->instr, rw->input_end); + if (rw->input_end) + memcpy(naya, rw->instr, rw->input_end); rw->instr = naya; rw->instr_size = size; @@ -5916,7 +5919,8 @@ static Scheme_Object *gen_replace(const char *name, int argc, Scheme_Object *arg total = len + prefix_len + (startpd - srcoffset); naya = (char *)scheme_malloc_atomic(total + more + 1); - memcpy(naya, prefix, prefix_len); + if (prefix_len) + memcpy(naya, prefix, prefix_len); memcpy(naya + prefix_len, source + srcoffset, startpd - srcoffset); memcpy(naya + prefix_len + (startpd - srcoffset), insert, len); if (more) { diff --git a/racket/src/racket/src/struct.c b/racket/src/racket/src/struct.c index 681174e2f8..dacd5c08b8 100644 --- a/racket/src/racket/src/struct.c +++ b/racket/src/racket/src/struct.c @@ -4697,11 +4697,13 @@ static Scheme_Object *make_name(const char *pre, const char *tn, int ltn, memcpy(name, pre, lp); total = lp; - memcpy(name + total, (ltn < 0) ? SCHEME_SYM_VAL((Scheme_Object *)tn) : tn, xltn); + if (xltn) + memcpy(name + total, (ltn < 0) ? SCHEME_SYM_VAL((Scheme_Object *)tn) : tn, xltn); total += xltn; memcpy(name + total, post1, lp1); total += lp1; - memcpy(name + total, (lfn < 0) ? SCHEME_SYM_VAL((Scheme_Object *)fn) : fn, xlfn); + if (xlfn) + memcpy(name + total, (lfn < 0) ? SCHEME_SYM_VAL((Scheme_Object *)fn) : fn, xlfn); total += xlfn; memcpy(name + total, post2, lp2); total += lp2; @@ -5092,7 +5094,8 @@ static Scheme_Object *_make_struct_type(Scheme_Object *base, } pa = MALLOC_N(Scheme_Object *, i + num_props); - memcpy(pa, struct_type->props, sizeof(Scheme_Object *) * i); + if (i) + memcpy(pa, struct_type->props, sizeof(Scheme_Object *) * i); num_props = i; diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index f7bff363ca..bd8de64217 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -1720,7 +1720,8 @@ static Scheme_Object *make_custodian_box(int argc, Scheme_Object *argv[]) cust_box_alloc = 2 * cust_box_alloc; } cbs = (Scheme_Custodian_Box **)scheme_malloc_atomic(cust_box_alloc * sizeof(Scheme_Custodian_Box *)); - memcpy(cbs, cust_boxes, cust_box_count * sizeof(Scheme_Custodian_Box *)); + if (cust_box_count) + memcpy(cbs, cust_boxes, cust_box_count * sizeof(Scheme_Custodian_Box *)); cust_boxes = cbs; } cust_boxes[cust_box_count++] = cb; @@ -6284,7 +6285,8 @@ void scheme_add_evt_worker(Evt ***evt_array, if (new_size < _scheme_last_type_) new_size = _scheme_last_type_; nevts = MALLOC_N(Evt*, new_size); - memcpy(nevts, (*evt_array), (*evt_size) * sizeof(Evt*)); + if (*evt_size) + memcpy(nevts, (*evt_array), (*evt_size) * sizeof(Evt*)); (*evt_array) = nevts; (*evt_size) = new_size; } diff --git a/racket/src/racket/src/validate.c b/racket/src/racket/src/validate.c index d749ed6790..8e37a26392 100644 --- a/racket/src/racket/src/validate.c +++ b/racket/src/racket/src/validate.c @@ -99,7 +99,8 @@ static void clearing_stack_push(struct Validate_Clearing *vc, int pos, int val) int *a, sz; sz = (vc->stacksize ? 2 * vc->stacksize : 32); a = (int *)scheme_malloc_atomic(sizeof(int) * sz); - memcpy(a, vc->stack, vc->stacksize * sizeof(int)); + if (vc->stacksize) + memcpy(a, vc->stack, vc->stacksize * sizeof(int)); vc->stacksize = sz; vc->stack = a; } @@ -114,7 +115,8 @@ static void noclear_stack_push(struct Validate_Clearing *vc, int pos) int *a, sz; sz = (vc->ncstacksize ? 2 * vc->ncstacksize : 32); a = (int *)scheme_malloc_atomic(sizeof(int) * sz); - memcpy(a, vc->ncstack, vc->ncstacksize * sizeof(int)); + if (vc->ncstacksize) + memcpy(a, vc->ncstack, vc->ncstacksize * sizeof(int)); vc->ncstacksize = sz; vc->ncstack = a; }