diff --git a/make/autoconf/configure.ac b/make/autoconf/configure.ac index fd3723b468366..05f2a51a7ed01 100644 --- a/make/autoconf/configure.ac +++ b/make/autoconf/configure.ac @@ -215,6 +215,9 @@ JDKOPT_SETUP_CODE_COVERAGE # AddressSanitizer JDKOPT_SETUP_ADDRESS_SANITIZER +# UndefinedBehaviorSanitizer +JDKOPT_SETUP_UNDEFINED_BEHAVIOR_SANITIZER + ############################################################################### # # Check dependencies for external and internal libraries. diff --git a/make/autoconf/jdk-options.m4 b/make/autoconf/jdk-options.m4 index 0cc6ed34e17b1..64f1bf09010d2 100644 --- a/make/autoconf/jdk-options.m4 +++ b/make/autoconf/jdk-options.m4 @@ -445,6 +445,41 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_ADDRESS_SANITIZER], AC_SUBST(ASAN_ENABLED) ]) +############################################################################### +# +# UndefinedBehaviorSanitizer +# +AC_DEFUN_ONCE([JDKOPT_SETUP_UNDEFINED_BEHAVIOR_SANITIZER], +[ + UTIL_ARG_ENABLE(NAME: ubsan, DEFAULT: false, RESULT: UBSAN_ENABLED, + DESC: [enable UndefinedBehaviorSanitizer], + CHECK_AVAILABLE: [ + AC_MSG_CHECKING([if UndefinedBehaviorSanitizer (ubsan) is available]) + if test "x$TOOLCHAIN_TYPE" = "xgcc" || + test "x$TOOLCHAIN_TYPE" = "xclang"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AVAILABLE=false + fi + ], + IF_ENABLED: [ + # GCC reports lots of likely false positives for stringop-truncation and format-overflow. + # Silence them for now. + UBSAN_CFLAGS="-fsanitize=undefined -fsanitize=float-divide-by-zero -Wno-stringop-truncation -Wno-format-overflow -fno-omit-frame-pointer -DUNDEFINED_BEHAVIOR_SANITIZER" + UBSAN_LDFLAGS="-fsanitize=undefined -fsanitize=float-divide-by-zero" + JVM_CFLAGS="$JVM_CFLAGS $UBSAN_CFLAGS" + JVM_LDFLAGS="$JVM_LDFLAGS $UBSAN_LDFLAGS" + CFLAGS_JDKLIB="$CFLAGS_JDKLIB $UBSAN_CFLAGS" + CFLAGS_JDKEXE="$CFLAGS_JDKEXE $UBSAN_CFLAGS" + CXXFLAGS_JDKLIB="$CXXFLAGS_JDKLIB $UBSAN_CFLAGS" + CXXFLAGS_JDKEXE="$CXXFLAGS_JDKEXE $UBSAN_CFLAGS" + LDFLAGS_JDKLIB="$LDFLAGS_JDKLIB $UBSAN_LDFLAGS" + LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE $UBSAN_LDFLAGS" + ]) + AC_SUBST(UBSAN_ENABLED) +]) + ################################################################################ # # Static build support. When enabled will generate static diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in index 9448cb9b7e885..1daed61c9831f 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in @@ -455,6 +455,9 @@ ifeq ($(ASAN_ENABLED), yes) endif endif +# UndefinedBehaviorSanitizer +UBSAN_ENABLED:=@UBSAN_ENABLED@ + # Necessary additional compiler flags to compile X11 X_CFLAGS:=@X_CFLAGS@ X_LIBS:=@X_LIBS@ diff --git a/make/common/NativeCompilation.gmk b/make/common/NativeCompilation.gmk index 3a9e5a1a57ee1..cf1cd2683cd5a 100644 --- a/make/common/NativeCompilation.gmk +++ b/make/common/NativeCompilation.gmk @@ -701,6 +701,19 @@ define SetupNativeCompilationBody $$(error No sources found for $1 when looking inside the dirs $$($1_SRC)) endif + ifeq ($$($1_TYPE), EXECUTABLE) + ifeq ($(UBSAN_ENABLED), true) + # We need to set the default options for UBSan. This needs to be included in every executable. + # Rather than copy and paste code to everything with a main function, we add an additional + # source file to every executable that exports __ubsan_default_options. + ifneq ($$(filter %.cpp %.cc, $$($1_SRCS)), ) + $1_SRCS += $(TOPDIR)/make/data/ubsan/ubsan_default_options.cpp + else + $1_SRCS += $(TOPDIR)/make/data/ubsan/ubsan_default_options.c + endif + endif + endif + # Calculate the expected output from compiling the sources $1_EXPECTED_OBJS_FILENAMES := $$(call replace_with_obj_extension, $$(notdir $$($1_SRCS))) $1_EXPECTED_OBJS := $$(addprefix $$($1_OBJECT_DIR)/, $$($1_EXPECTED_OBJS_FILENAMES)) diff --git a/make/data/ubsan/ubsan_default_options.c b/make/data/ubsan/ubsan_default_options.c new file mode 100644 index 0000000000000..ee426ebbc39fe --- /dev/null +++ b/make/data/ubsan/ubsan_default_options.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef UNDEFINED_BEHAVIOR_SANITIZER +#error "Build misconfigured, preprocessor macro UNDEFINED_BEHAVIOR_SANITIZER should be defined" +#endif + +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif + +#if (defined(__GNUC__) && !defined(__clang__)) || __has_attribute(visibility) +#define ATTRIBUTE_DEFAULT_VISIBILITY __attribute__((visibility("default"))) +#else +#define ATTRIBUTE_DEFAULT_VISIBILITY +#endif + +#if (defined(__GNUC__) && !defined(__clang__)) || __has_attribute(used) +#define ATTRIBUTE_USED __attribute__((used)) +#else +#define ATTRIBUTE_USED +#endif + +// Override weak symbol exposed by UBSan to override default options. This is called by UBSan +// extremely early during library loading, before main is called. We need to override the default +// options because by default UBSan only prints a warning for each occurrence. We want jtreg tests +// to fail when undefined behavior is encountered. We also want a full stack trace for the offending +// thread so it is easier to track down. You can override these options by setting the environment +// variable UBSAN_OPTIONS. +ATTRIBUTE_DEFAULT_VISIBILITY ATTRIBUTE_USED const char* __ubsan_default_options() { + return "halt_on_error=1,print_stacktrace=1"; +} diff --git a/make/data/ubsan/ubsan_default_options.cpp b/make/data/ubsan/ubsan_default_options.cpp new file mode 100644 index 0000000000000..dbebb5b2977e0 --- /dev/null +++ b/make/data/ubsan/ubsan_default_options.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +extern "C" { + +#include "./ubsan_default_options.c" + +} // extern "C"