improve ubsan support
Provide `--enable-ubsan` to simplify `-fsanitize=undefined` builds, where alignment and floating-point divide-by-zero need to be disabled to get useful results. Also, repair undefined behavior exposed by the test suite. Most of the repairs are avoiding `memset(..., NULL, 0)` --- which is an unhelpful requirement, IMO. The other two repairs are worthwhile but unlikely to have caused trouble.
This commit is contained in:
parent
153dc01ccd
commit
c4d7e8bf1b
17
racket/src/configure
vendored
17
racket/src/configure
vendored
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -136,6 +136,7 @@ inline static int create_blank_owner_set(NewGC *gc)
|
|||
gc->owner_table_size = curr_size;
|
||||
|
||||
naya = (OTEntry **)ofm_malloc(curr_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),
|
||||
|
|
|
@ -17,6 +17,7 @@ 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));
|
||||
|
||||
if (roots->count)
|
||||
memcpy((void *)new_roots, (void *)roots->roots, sizeof(uintptr_t) * roots->count);
|
||||
|
||||
if (roots->roots)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1372,6 +1372,7 @@ 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);
|
||||
if (oldsize)
|
||||
memcpy(naya, v, oldsize);
|
||||
if (v)
|
||||
munmap(v, (oldsize + SECTOR_SEGMENT_SIZE - 1) >> LOG_SECTOR_SEGMENT_SIZE);
|
||||
|
|
|
@ -1125,6 +1125,7 @@ void scheme_new_mark_segment(Scheme_Thread *p)
|
|||
seg = scheme_malloc_allow_interior(sizeof(Scheme_Cont_Mark) * SCHEME_MARK_SEGMENT_SIZE);
|
||||
segs[c] = seg;
|
||||
|
||||
if (c)
|
||||
memcpy(segs, p->cont_mark_stack_segments, c * sizeof(Scheme_Cont_Mark *));
|
||||
|
||||
p->cont_mark_seg_count++;
|
||||
|
|
|
@ -5308,6 +5308,7 @@ 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);
|
||||
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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -852,6 +852,7 @@ 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));
|
||||
if (pos)
|
||||
memcpy(a, mt->cdata_map, pos * sizeof(Scheme_Object *));
|
||||
mt->cdata_map = a;
|
||||
}
|
||||
|
|
|
@ -2677,6 +2677,7 @@ 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;
|
||||
if (nth_app)
|
||||
lam->ir_info->arg_type_contributors[i] |= (1 << (nth_app-1));
|
||||
} else
|
||||
widen_to_top = 1;
|
||||
|
|
|
@ -665,6 +665,7 @@ string_write_bytes(Scheme_Output_Port *port,
|
|||
memcpy(is->string, old, is->index);
|
||||
}
|
||||
|
||||
if (len)
|
||||
memcpy(is->string + is->index, str + d, len);
|
||||
is->index += len;
|
||||
|
||||
|
|
|
@ -1235,6 +1235,7 @@ static void print_this_string(PrintParams *pp, const char *str, int offset, int
|
|||
memcpy(pp->print_buffer, oldstr, pp->print_position);
|
||||
}
|
||||
|
||||
if (len)
|
||||
memcpy(pp->print_buffer + pp->print_position, str + offset, len);
|
||||
pp->print_position += len;
|
||||
pp->print_offset += len;
|
||||
|
@ -4144,6 +4145,7 @@ 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));
|
||||
if (printers_count)
|
||||
memcpy(naya, printers, sizeof(Scheme_Type_Printer) * printers_count);
|
||||
printers_count = stype + 10;
|
||||
printers = naya;
|
||||
|
|
|
@ -2448,6 +2448,7 @@ 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);
|
||||
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,6 +2965,7 @@ 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);
|
||||
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,
|
||||
|
@ -3012,6 +3014,7 @@ static void read_more_from_regport(Regwork *rw, rxpos need_total)
|
|||
size = 16;
|
||||
|
||||
naya = (char *)scheme_malloc_atomic(size);
|
||||
if (rw->input_end)
|
||||
memcpy(naya, rw->instr, rw->input_end);
|
||||
|
||||
rw->instr = naya;
|
||||
|
@ -5916,6 +5919,7 @@ 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);
|
||||
if (prefix_len)
|
||||
memcpy(naya, prefix, prefix_len);
|
||||
memcpy(naya + prefix_len, source + srcoffset, startpd - srcoffset);
|
||||
memcpy(naya + prefix_len + (startpd - srcoffset), insert, len);
|
||||
|
|
|
@ -4697,10 +4697,12 @@ static Scheme_Object *make_name(const char *pre, const char *tn, int ltn,
|
|||
|
||||
memcpy(name, pre, lp);
|
||||
total = lp;
|
||||
if (xltn)
|
||||
memcpy(name + total, (ltn < 0) ? SCHEME_SYM_VAL((Scheme_Object *)tn) : tn, xltn);
|
||||
total += xltn;
|
||||
memcpy(name + total, post1, lp1);
|
||||
total += lp1;
|
||||
if (xlfn)
|
||||
memcpy(name + total, (lfn < 0) ? SCHEME_SYM_VAL((Scheme_Object *)fn) : fn, xlfn);
|
||||
total += xlfn;
|
||||
memcpy(name + total, post2, lp2);
|
||||
|
@ -5092,6 +5094,7 @@ static Scheme_Object *_make_struct_type(Scheme_Object *base,
|
|||
}
|
||||
|
||||
pa = MALLOC_N(Scheme_Object *, i + num_props);
|
||||
if (i)
|
||||
memcpy(pa, struct_type->props, sizeof(Scheme_Object *) * i);
|
||||
|
||||
num_props = i;
|
||||
|
|
|
@ -1720,6 +1720,7 @@ 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 *));
|
||||
if (cust_box_count)
|
||||
memcpy(cbs, cust_boxes, cust_box_count * sizeof(Scheme_Custodian_Box *));
|
||||
cust_boxes = cbs;
|
||||
}
|
||||
|
@ -6284,6 +6285,7 @@ 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);
|
||||
if (*evt_size)
|
||||
memcpy(nevts, (*evt_array), (*evt_size) * sizeof(Evt*));
|
||||
(*evt_array) = nevts;
|
||||
(*evt_size) = new_size;
|
||||
|
|
|
@ -99,6 +99,7 @@ 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);
|
||||
if (vc->stacksize)
|
||||
memcpy(a, vc->stack, vc->stacksize * sizeof(int));
|
||||
vc->stacksize = sz;
|
||||
vc->stack = a;
|
||||
|
@ -114,6 +115,7 @@ 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);
|
||||
if (vc->ncstacksize)
|
||||
memcpy(a, vc->ncstack, vc->ncstacksize * sizeof(int));
|
||||
vc->ncstacksize = sz;
|
||||
vc->ncstack = a;
|
||||
|
|
Loading…
Reference in New Issue
Block a user