diff --git a/DEPS b/DEPS index c34128c97be..ba4bdacc555 100644 --- a/DEPS +++ b/DEPS @@ -19,6 +19,7 @@ allowed_hosts = [ 'dart.googlesource.com', 'dart-internal.googlesource.com', 'fuchsia.googlesource.com', + 'llvm.googlesource.com', ] vars = { @@ -42,6 +43,7 @@ vars = { # Chromium git "chromium_git": "https://chromium.googlesource.com", "fuchsia_git": "https://fuchsia.googlesource.com", + "llvm_git": "https://llvm.googlesource.com", # Checked-in SDK version. The checked-in SDK is a Dart SDK distribution in a # cipd package used to run Dart scripts in the build and test infrastructure, @@ -95,6 +97,8 @@ vars = { "devtools_rev": "026f0adf03725fbab24d601ac74c811808f258e5", "icu_rev": "81d656878ec611cb0b42d52c82e9dae93920d9ba", "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1", + "libcxx_rev": "44079a4cc04cdeffb9cfe8067bfb3c276fb2bab0", + "libcxxabi_rev": "2ce528fb5e0f92e57c97ec3ff53b75359d33af12", "libprotobuf_rev": "24487dd1045c7f3d64a21f38a3f0c06cc4cf2edb", "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783", "perfetto_rev": "b8da07095979310818f0efde2ef3c69ea70d62c5", @@ -275,6 +279,12 @@ deps = { Var("chromium_git") + "/chromium/src/third_party/zlib.git" + "@" + Var("zlib_rev"), + Var("dart_root") + "/third_party/libcxx": + Var("llvm_git") + "/llvm-project/libcxx" + "@" + Var("libcxx_rev"), + + Var("dart_root") + "/third_party/libcxxabi": + Var("llvm_git") + "/llvm-project/libcxxabi" + "@" + Var("libcxxabi_rev"), + Var("dart_root") + "/third_party/boringssl": Var("dart_git") + "boringssl_gen.git" + "@" + Var("boringssl_gen_rev"), Var("dart_root") + "/third_party/boringssl/src": diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 35e8cd4d3b5..be9bb113212 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -222,6 +222,8 @@ if (!is_clang && (is_asan || is_lsan || is_msan || is_tsan || is_ubsan)) { is_clang = true } +use_flutter_cxx = is_msan || is_android + # ============================================================================= # TARGET DEFAULTS # ============================================================================= @@ -235,6 +237,7 @@ if (!is_clang && (is_asan || is_lsan || is_msan || is_tsan || is_ubsan)) { # duplication in each target below. _native_compiler_configs = [ "//build/config/compiler:compiler", + "//build/config/compiler:cxx_version_default", "//build/config/compiler:clang_stackrealign", "//build/config/compiler:compiler_arm_fpu", "//build/config/compiler:compiler_arm_thumb", @@ -243,6 +246,14 @@ _native_compiler_configs = [ "//build/config/compiler:no_rtti", "//build/config/compiler:runtime_library", ] + +if (use_flutter_cxx) { + _native_compiler_configs += [ + "//third_party/libcxxabi:libcxxabi_config", + "//third_party/libcxx:libcxx_config", + ] +} + if (is_win) { _native_compiler_configs += [ "//build/config/win:lean_and_mean", @@ -419,6 +430,31 @@ if (is_win) { } } +# Sets default dependencies for executable and shared_library targets. +# +# Variables +# no_default_deps: If true, no standard dependencies will be added. +if (use_flutter_cxx) { + foreach(_target_type, + [ + "executable", + "loadable_module", + "shared_library", + ]) { + template(_target_type) { + target(_target_type, target_name) { + forward_variables_from(invoker, "*", [ "no_default_deps" ]) + if (!defined(deps)) { + deps = [] + } + if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) { + deps += [ "//third_party/libcxx" ] + } + } + } + } +} + # ============================================================================== # COMPONENT SETUP # ============================================================================== diff --git a/build/config/c++/c++.gni b/build/config/c++/c++.gni new file mode 100644 index 00000000000..a005d3a0aef --- /dev/null +++ b/build/config/c++/c++.gni @@ -0,0 +1,9 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +declare_args() { + # Use libc++ (buildtools/third_party/libc++ and + # buildtools/third_party/libc++abi) instead of stdlibc++ as standard library. + use_custom_libcxx = false +} diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 655ffba6e5a..fb45d1ec551 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -23,6 +23,7 @@ if (is_win) { import("//build/config/win/visual_studio_version.gni") } +import("//build/config/c++/c++.gni") import("//build/toolchain/ccache.gni") # default_include_dirs --------------------------------------------------------- @@ -135,6 +136,14 @@ config("compiler") { cflags += [ "-fsanitize=undefined" ] ldflags += [ "-fsanitize=undefined" ] } + + if (use_custom_libcxx) { + cflags_cc += [ "-nostdinc++" ] + include_dirs = [ + "//buildtools/third_party/libc++/trunk/include", + "//buildtools/third_party/libc++abi/trunk/include", + ] + } } if (is_clang && is_debug) { @@ -250,8 +259,19 @@ config("compiler") { } if (is_android || is_linux || is_mac || is_fuchsia) { - cflags += [ "-fPIE" ] - ldflags += [ "-fPIE" ] + if (use_flutter_cxx) { + # shared_library_config isn't transitive, so we don't automatically get + # another versions of libcxx with and without -fPIC. Properly setting this + # up so only shard libraries pay the extra cost fPIC over fPIE means + # something like separate GN toolchains like in the Fuchsia GN build. For + # now, globally enabling fPIC is okay because it is limited to test-only + # builds. + cflags += [ "-fPIC" ] + ldflags += [ "-fPIC" ] + } else { + cflags += [ "-fPIE" ] + ldflags += [ "-fPIE" ] + } } # Linux-specific compiler flags setup. @@ -418,6 +438,56 @@ config("compiler") { } } +config("cxx_version_default") { + if (is_win) { + cc_std = [ "/std:c++17" ] + } else { + cc_std = [ "-std=c++17" ] + } + cflags_cc = cc_std + cflags_objcc = cc_std +} + +config("cxx_version_11") { + if (is_win) { + cc_std = [ "/std:c++11" ] + } else { + cc_std = [ "-std=c++11" ] + } + cflags_cc = cc_std + cflags_objcc = cc_std +} + +config("cxx_version_14") { + if (is_win) { + cc_std = [ "/std:c++14" ] + } else { + cc_std = [ "-std=c++14" ] + } + cflags_cc = cc_std + cflags_objcc = cc_std +} + +config("cxx_version_17") { + if (is_win) { + cc_std = [ "/std:c++17" ] + } else { + cc_std = [ "-std=c++17" ] + } + cflags_cc = cc_std + cflags_objcc = cc_std +} + +config("cxx_version_20") { + if (is_win) { + cc_std = [ "/std:c++20" ] + } else { + cc_std = [ "-std=c++20" ] + } + cflags_cc = cc_std + cflags_objcc = cc_std +} + # This is separate from :compiler_codegen (and not even a sub-config there) # so that some targets can remove it from the list with: # configs -= [ "//build/config/compiler:clang_stackrealign" ] @@ -462,6 +532,8 @@ config("compiler_arm_thumb") { config("runtime_library") { cflags = [] + cflags_cc = [] + cflags_objcc = [] defines = [] ldflags = [] lib_dirs = [] @@ -483,6 +555,16 @@ config("runtime_library") { ] } + if (use_flutter_cxx) { + cflags_cc += [ "-nostdinc++" ] + cflags_objcc += [ "-nostdinc++" ] + ldflags += [ "-nostdlib++" ] + include_dirs = [ + "//third_party/libcxx/include", + "//third_party/libcxxabi/include", + ] + } + if (is_linux) { libs += [ "dl", diff --git a/build/config/linux/BUILD.gn b/build/config/linux/BUILD.gn index a8d08d571ff..ac81ac075ec 100644 --- a/build/config/linux/BUILD.gn +++ b/build/config/linux/BUILD.gn @@ -15,10 +15,12 @@ config("sdk") { # Explicitly use static linking for libstdc++ and libgcc to minimize # dependencies. - ldflags += [ - "-static-libgcc", - "-static-libstdc++", - ] + if (!use_flutter_cxx) { + ldflags += [ + "-static-libgcc", + "-static-libstdc++", + ] + } if (sysroot != "") { cflags += [ "--sysroot=" + sysroot ] diff --git a/build/config/mac/BUILD.gn b/build/config/mac/BUILD.gn index b4bef006ff2..ba792e33dec 100644 --- a/build/config/mac/BUILD.gn +++ b/build/config/mac/BUILD.gn @@ -6,10 +6,12 @@ import("//build/config/sysroot.gni") import("../clang/clang.gni") config("sdk") { - ldflags = [ - "-nostdlib++", - "${clang_prefix}/../lib/libc++.a", - ] + if (!use_flutter_cxx) { + ldflags = [ + "-nostdlib++", + "${clang_prefix}/../lib/libc++.a", + ] + } } # On Mac, this is used for everything except static libraries. diff --git a/build/config/sanitizers/sanitizers.gni b/build/config/sanitizers/sanitizers.gni index bf4741b6e10..2fcf3163f42 100644 --- a/build/config/sanitizers/sanitizers.gni +++ b/build/config/sanitizers/sanitizers.gni @@ -3,12 +3,6 @@ # found in the LICENSE file. declare_args() { - # Use libc++ (buildtools/third_party/libc++ and - # buildtools/third_party/libc++abi) instead of stdlibc++ as standard library. - # This is intended to be used for instrumented builds. - use_custom_libcxx = - (is_asan && is_linux) || is_lsan || is_msan || is_tsan || is_ubsan - # Track where uninitialized memory originates from. From fastest to slowest: # 0 - no tracking, 1 - track only the initial allocation site, 2 - track the # chain of stores leading from allocation site to use site. diff --git a/build/secondary/third_party/libcxx/BUILD.gn b/build/secondary/third_party/libcxx/BUILD.gn new file mode 100644 index 00000000000..c01d111df99 --- /dev/null +++ b/build/secondary/third_party/libcxx/BUILD.gn @@ -0,0 +1,117 @@ +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config("libcxx_config") { + defines = [ "_LIBCPP_DISABLE_AVAILABILITY=1" ] + include_dirs = [ "//build/secondary/third_party/libcxx/config" ] +} + +config("src_include") { + include_dirs = [ "src" ] +} + +source_set("libcxx") { + sources = [ + "src/algorithm.cpp", + "src/any.cpp", + "src/bind.cpp", + "src/charconv.cpp", + "src/chrono.cpp", + "src/condition_variable.cpp", + "src/condition_variable_destructor.cpp", + "src/debug.cpp", + "src/exception.cpp", + "src/filesystem/directory_iterator.cpp", + "src/filesystem/filesystem_common.h", + "src/filesystem/int128_builtins.cpp", + "src/filesystem/operations.cpp", + "src/functional.cpp", + "src/future.cpp", + "src/hash.cpp", + "src/ios.cpp", + "src/ios.instantiations.cpp", + "src/iostream.cpp", + "src/locale.cpp", + "src/memory.cpp", + "src/mutex.cpp", + "src/mutex_destructor.cpp", + "src/new.cpp", + "src/optional.cpp", + "src/random.cpp", + "src/regex.cpp", + "src/ryu/d2fixed.cpp", + "src/ryu/d2s.cpp", + "src/ryu/f2s.cpp", + "src/shared_mutex.cpp", + "src/stdexcept.cpp", + "src/string.cpp", + "src/strstream.cpp", + "src/system_error.cpp", + "src/thread.cpp", + "src/typeinfo.cpp", + "src/utility.cpp", + "src/valarray.cpp", + "src/variant.cpp", + "src/vector.cpp", + ] + + deps = [ "//third_party/libcxxabi" ] + + # TODO(goderbauer): remove when all sources build with LTO for android_arm64 and android_x64. + if (is_android && (current_cpu == "arm64" || current_cpu == "x64")) { + sources -= [ "src/new.cpp" ] + deps += [ ":libcxx_nolto" ] + } + + public_configs = [ + ":libcxx_config", + "//third_party/libcxxabi:libcxxabi_config", + ] + + defines = [ + "_LIBCPP_NO_EXCEPTIONS", + "_LIBCPP_NO_RTTI", + "_LIBCPP_BUILDING_LIBRARY", + "LIBCXX_BUILDING_LIBCXXABI", + ] + + # While no translation units in Flutter engine enable RTTI, it may be enabled + # in one of the third party dependencies. This mirrors the configuration in + # libcxxabi. + configs -= [ "//build/config/compiler:no_rtti" ] + configs += [ "//build/config/compiler:rtti" ] + + # libcxx requires C++20 + configs -= [ "//build/config/compiler:cxx_version_default" ] + configs += [ "//build/config/compiler:cxx_version_20" ] + + configs += [ ":src_include" ] + + if (is_clang) { + # shared_mutex.cpp and debug.cpp are purposefully in violation. + cflags_cc = [ "-Wno-thread-safety-analysis" ] + } +} + +source_set("libcxx_nolto") { + visibility = [ ":*" ] + + sources = [ "src/new.cpp" ] + + cflags_cc = [ "-fno-lto" ] + + deps = [ "//third_party/libcxxabi" ] + + public_configs = [ + ":libcxx_config", + "//third_party/libcxxabi:libcxxabi_config", + ] + + defines = [ + "_LIBCPP_NO_EXCEPTIONS", + "_LIBCPP_NO_RTTI", + "_LIBCPP_BUILDING_LIBRARY", + "LIBCXX_BUILDING_LIBCXXABI", + ] +} diff --git a/build/secondary/third_party/libcxx/config/__config_site b/build/secondary/third_party/libcxx/config/__config_site new file mode 100644 index 00000000000..106c24fc361 --- /dev/null +++ b/build/secondary/third_party/libcxx/config/__config_site @@ -0,0 +1,39 @@ +#ifndef _LIBCPP_CONFIG_SITE +#define _LIBCPP_CONFIG_SITE + +/* #undef _LIBCPP_ABI_VERSION */ +/* #undef _LIBCPP_ABI_UNSTABLE */ +/* #undef _LIBCPP_ABI_FORCE_ITANIUM */ +/* #undef _LIBCPP_ABI_FORCE_MICROSOFT */ +/* #undef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT */ +/* #undef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE */ +/* #undef _LIBCPP_HAS_NO_STDIN */ +/* #undef _LIBCPP_HAS_NO_STDOUT */ +/* #undef _LIBCPP_HAS_NO_THREADS */ +/* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */ +/* #undef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS */ +/* #undef _LIBCPP_HAS_MUSL_LIBC */ +/* #undef _LIBCPP_HAS_THREAD_API_PTHREAD */ +/* #undef _LIBCPP_HAS_THREAD_API_EXTERNAL */ +/* #undef _LIBCPP_HAS_THREAD_API_WIN32 */ +/* #undef _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL */ +/* #undef _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS */ +#define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +/* #undef _LIBCPP_NO_VCRUNTIME */ +/* #undef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION */ +/* #undef _LIBCPP_ABI_NAMESPACE */ +/* #undef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY */ +/* #undef _LIBCPP_HAS_PARALLEL_ALGORITHMS */ +/* #undef _LIBCPP_HAS_NO_RANDOM_DEVICE */ +/* #undef _LIBCPP_HAS_NO_LOCALIZATION */ + +#define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES + +// This is a workaround for BoringSSL, which is compiled in C11 mode +// and includes stdatomic.h. Defining this macro will cause stdatomic.h +// to redirect to the next version of that header in the include path. +#if !defined(__cplusplus) && defined(__clang__) +#define _LIBCPP_COMPILER_CLANG_BASED +#endif + +#endif // _LIBCPP_CONFIG_SITE diff --git a/build/secondary/third_party/libcxxabi/BUILD.gn b/build/secondary/third_party/libcxxabi/BUILD.gn new file mode 100644 index 00000000000..7a101ac04ea --- /dev/null +++ b/build/secondary/third_party/libcxxabi/BUILD.gn @@ -0,0 +1,73 @@ +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config("libcxxabi_config") { + common_cc_flags = [ + "-nostdinc++", + "-fvisibility=hidden", + + # Otherwise infinite recursion in __dynamic_cast. + "-fno-sanitize=undefined", + ] + + cflags_cc = common_cc_flags + cflags_objcc = common_cc_flags + + include_dirs = [ "include" ] + + if (is_ios) { + ldflags = [ "-Wl,-unexported_symbols_list," + + rebase_path("lib/new-delete.exp", root_build_dir) ] + } +} + +source_set("libcxxabi") { + visibility = [ "../libcxx:*" ] + + public_configs = [ ":libcxxabi_config" ] + + defines = [ + "_LIBCPP_BUILDING_LIBRARY", + "_LIBCXXABI_BUILDING_LIBRARY", + "LIBCXXABI_SILENT_TERMINATE", + "_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS", + ] + + sources = [] + + # Compile libcxx ABI using C++11. This replicates the rule in the + # CMakeLists on the "cxx_abiobjects" target. + configs -= [ "//build/config/compiler:cxx_version_default" ] + configs += [ "//build/config/compiler:cxx_version_20" ] + + configs += [ "//third_party/libcxx:src_include" ] + + # Third party dependencies may depend on RTTI. Add support for the same in + # cxxabi. + configs -= [ "//build/config/compiler:no_rtti" ] + configs += [ "//build/config/compiler:rtti" ] + + sources += [ + "src/abort_message.cpp", + "src/cxa_aux_runtime.cpp", + "src/cxa_default_handlers.cpp", + "src/cxa_demangle.cpp", + "src/cxa_exception.cpp", + "src/cxa_exception_storage.cpp", + "src/cxa_handlers.cpp", + "src/cxa_personality.cpp", + "src/cxa_thread_atexit.cpp", + "src/cxa_vector.cpp", + "src/cxa_virtual.cpp", + "src/fallback_malloc.cpp", + "src/private_typeinfo.cpp", + "src/stdlib_exception.cpp", + "src/stdlib_stdexcept.cpp", + "src/stdlib_typeinfo.cpp", + ] + + if (!(is_tsan && is_linux)) { + sources += [ "src/cxa_guard.cpp" ] + } +} diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 71e87ae0840..eb22d0be8cb 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -15812,9 +15812,16 @@ void ObjectPool::DebugPrint() const { uword pc = RawValueAt(i); uintptr_t start = 0; char* name = NativeSymbolResolver::LookupSymbolName(pc, &start); + char* dso_name; + uword dso_base; if (name != nullptr) { THR_Print("%s (native function)\n", name); NativeSymbolResolver::FreeSymbolName(name); + } else if (NativeSymbolResolver::LookupSharedObject(pc, &dso_base, + &dso_name)) { + uword dso_offset = pc - dso_base; + THR_Print("%s+0x%" Px " (native function)\n", dso_name, dso_offset); + NativeSymbolResolver::FreeSymbolName(dso_name); } else { THR_Print("0x%" Px " (native function)\n", pc); }