| # Copyright 2020 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/config/zircon/levels.gni") |
| import("../libc.gni") |
| |
| group("scudo") { |
| if (!variant_replaces_allocator) { |
| # If we are using a sanitizer that replaces the allocator, do not include |
| # scudo in libc so we can use the sanitizer allocator. Stubs are provided |
| # that replace scudo's definitions. |
| deps = [ ":scudo-allocator" ] |
| } |
| } |
| |
| scudo_common_vars = { |
| dir = scudo |
| include_dirs = [ |
| ".", |
| dir, |
| "$dir/include", |
| |
| # The gwp_asan code uses #include "gwp_asan/...". |
| "${gwp_asan}/..", |
| ] |
| |
| configs = [ ":common.config" ] |
| deps = [ |
| "//src/zircon/lib/zircon", |
| "//zircon/system/ulib/sync", |
| ] |
| } |
| |
| libc_source_set("scudo-allocator") { |
| forward_variables_from(scudo_common_vars, "*") |
| |
| sources = [ |
| "checksum.cpp", |
| "common.cpp", |
| "crc32_hw.cpp", |
| "flags.cpp", |
| "flags_parser.cpp", |
| "fuchsia.cpp", |
| "linux.cpp", |
| "mem_map.cpp", |
| "mem_map_fuchsia.cpp", |
| "release.cpp", |
| "report.cpp", |
| "string_utils.cpp", |
| "timing.cpp", |
| ] |
| |
| # The code needs to be compiled separately for production and test use for |
| # two reasons. |
| # |
| # The first reason only affects the flag-parsing code (src/flags.cpp): it |
| # uses the `__scudo_default_options` callback function. The test code wants |
| # to define this to set special options needed by certain tests. But |
| # defining it by that name will also affect the production Scudo built into |
| # libc, which the test should not do (and it makes it very hard to e.g. debug |
| # the test linked against a libc containing a slightly different version of |
| # Scudo than the code under test). So both the flag-parsing code and the |
| # test code must be compiled with `-D__scudo_default_options=<some other |
| # name>` to make the test code safe. |
| # |
| # TODO(https://fxbug.dev/42142757): The second reason is similar but more subtle and it |
| # affects much of the code, both the Scudo code proper and the gwp_asan code |
| # it incorporates. These both use thread-local state that is directly |
| # located in the thread structure when the code is built into libc, because |
| # normal `thread_local` C++ variables are not available inside libc itself |
| # (due to implementation constraints in the dynamic linker). If the test |
| # code is built the same way, then it will clobber the thread-local state of |
| # the libc Scudo/gwp_asan code, which the test should not do. |
| non_test_deps = [ |
| ":gwp_asan", |
| ":libc", |
| ":wrappers", |
| ] |
| testonly_deps = [ |
| ":gwp_asan.testonly", |
| ":testonly", |
| ] |
| } |
| |
| config("common.config") { |
| visibility = [ ":*" ] |
| |
| # This enables Scudo DCHECK* when ZX_DEBUG_ASSERT is enabled. |
| if (zx_assert_level > 1) { |
| scudo_debug = 1 |
| } else { |
| scudo_debug = 0 |
| } |
| |
| defines = [ |
| "GWP_ASAN_HOOKS=1", |
| "SCUDO_DEBUG=$scudo_debug", |
| "SCUDO_ENABLE_HOOKS=1", |
| "SCUDO_USE_CUSTOM_CONFIG=1", |
| |
| # TODO(https://fxbug.dev/42082832): Scudo, which lives in the C library, cannot |
| # see the hooks defined by the wrapper-tests in the test executable. |
| "SCUDO_ENABLE_HOOKS_TESTS=0", |
| ] |
| |
| include_dirs = [ "." ] |
| } |
| |
| # These define the public API entry points (malloc et al). They cannot be |
| # included in the test code without polluting the test harness and other |
| # unrelated code with the allocator code under test. So they are only |
| # included in libc itself, not in the test build. |
| libc_source_set("wrappers") { |
| forward_variables_from(scudo_common_vars, "*") |
| |
| sources = [ |
| "wrappers_c.cpp", |
| # TODO(https://fxbug.dev/42082846): Disable c++ wrappers provided by Scudo. |
| #"wrappers_cpp.cpp", |
| ] |
| |
| non_test_deps = [ ":libc" ] |
| } |
| |
| group("libc") { |
| visibility = [ ":*" ] |
| |
| public_configs = [ ":libc.config" ] |
| |
| public_deps = [ |
| # The local headers introduced by libc.config (below) use libc internals, |
| # so they need access to the internal headers. |
| "//zircon/third_party/ulib/musl:musl_internal", |
| ] |
| } |
| |
| config("libc.config") { |
| visibility = [ ":*" ] |
| |
| defines = [ |
| # Tell the scudo and gwp_asan code to use our headers. |
| "SCUDO_HAS_PLATFORM_TLS_SLOT=1", |
| "GWP_ASAN_PLATFORM_TLS_HEADER=<gwp_asan_platform_tls_slot.h>", |
| |
| # GWP-ASan is opt-in via the SCUDO_OPTIONS environment variable. |
| "GWP_ASAN_DEFAULT_ENABLED=false", |
| ] |
| |
| # This library is linked into libc, which is used by libfuzzer. |
| # Don't instrument it to avoid getting noise in code coverage. |
| # TODO(https://fxbug.dev/42099340): Once a cleaner solution is found, remove this. |
| configs = [ "//build/config/zircon:no_fuzzer" ] |
| } |
| |
| group("testonly") { |
| visibility = [ ":*" ] |
| |
| public_configs = [ ":testonly.config" ] |
| } |
| |
| config("testonly.config") { |
| visibility = [ ":*" ] |
| |
| # TODO(crbug.com/gn/214): testonly = true |
| |
| # The test version avoids that symbol name since it also affects the system |
| # libc and not only the code under test. Instead it renames the function to |
| # a safe name for the test. The test code that defines its own function by |
| # this name also uses this config so it renames its definition to match. |
| defines = [ "__scudo_default_options=testonly_scudo_default_options" ] |
| } |
| |
| gwp_asan_common_vars = { |
| forward_variables_from(scudo_common_vars, "*") |
| dir = gwp_asan |
| } |
| |
| libc_source_set("gwp_asan") { |
| forward_variables_from(gwp_asan_common_vars, "*") |
| |
| sources = [ |
| "guarded_pool_allocator.cpp", |
| "guarded_pool_allocator.h", |
| "mutex.h", |
| "optional/backtrace.h", |
| "optional/backtrace_fuchsia.cpp", |
| "optional/printf.h", |
| "optional/segv_handler.h", |
| "optional/segv_handler_fuchsia.cpp", |
| "platform_specific/guarded_pool_allocator_fuchsia.cpp", |
| "platform_specific/guarded_pool_allocator_fuchsia.h", |
| "platform_specific/guarded_pool_allocator_tls.h", |
| "platform_specific/mutex_fuchsia.cpp", |
| "platform_specific/mutex_fuchsia.h", |
| "platform_specific/utilities_fuchsia.cpp", |
| ] |
| public_deps = [ ":gwp-asan-common" ] |
| |
| non_test_deps = [ |
| ":gwp-asan-info", |
| ":libc", |
| ] |
| testonly_deps = [ ":testonly" ] |
| } |
| |
| libc_source_set("gwp-asan-info") { |
| forward_variables_from(gwp_asan_common_vars, "*", [ "dir" ]) |
| |
| deps += [ |
| ":gwp-asan-common", |
| ":libc", |
| ] |
| sources = [ |
| "gwp_asan_info.cc", |
| "gwp_asan_note.S", |
| ] |
| } |
| |
| # Crash handlers should depend on this target. |
| source_set("gwp-asan-common") { |
| public_configs = [ ":gwp-asan-common-config" ] |
| sources = [ |
| "${gwp_asan}/common.cpp", |
| "${gwp_asan}/common.h", |
| "${gwp_asan}/crash_handler.cpp", |
| "${gwp_asan}/crash_handler.h", |
| "${gwp_asan}/definitions.h", |
| "${gwp_asan}/options.h", |
| "${gwp_asan}/platform_specific/common_fuchsia.cpp", |
| "${gwp_asan}/stack_trace_compressor.cpp", |
| "${gwp_asan}/stack_trace_compressor.h", |
| "gwp_asan_info.h", |
| ] |
| } |
| |
| config("gwp-asan-common-config") { |
| include_dirs = [ "${gwp_asan}/.." ] |
| } |
| |
| # This is included in libc-unittests and standalone core-tests. |
| libc_test("unittests") { |
| forward_variables_from(scudo_common_vars, "*") |
| |
| sources = [ |
| "tests/atomic_test.cpp", |
| "tests/bytemap_test.cpp", |
| "tests/checksum_test.cpp", |
| "tests/chunk_test.cpp", |
| "tests/combined_test.cpp", |
| "tests/flags_test.cpp", |
| "tests/list_test.cpp", |
| "tests/map_test.cpp", |
| "tests/mutex_test.cpp", |
| "tests/primary_test.cpp", |
| "tests/quarantine_test.cpp", |
| "tests/release_test.cpp", |
| "tests/report_test.cpp", |
| "tests/scudo_unit_test_main.cpp", |
| "tests/secondary_test.cpp", |
| "tests/size_class_map_test.cpp", |
| "tests/stats_test.cpp", |
| "tests/strings_test.cpp", |
| "tests/timing_test.cpp", |
| "tests/tsd_test.cpp", |
| "tests/vector_test.cpp", |
| ] |
| |
| deps += [ |
| ":gwp_asan-unittests", |
| ":scudo-allocator.testonly", |
| ] |
| |
| # The public API tests both assume Scudo's behavior rather than purely kosher |
| # standard behavior and they include testing error cases. The instrumented |
| # runtimes' allocators often make error cases or dubiously kosher uses fatal. |
| if (!variant_replaces_allocator) { |
| deps += [ ":wrapper-tests" ] |
| } |
| |
| # Suppress warnings from third party code |
| configs += [ "//build/config:Wno-extra-semi" ] |
| } |
| |
| # These tests use the public API, so they are testing what's actually in libc |
| # rather than the isolated test code. |
| libc_test("wrapper-tests") { |
| forward_variables_from(scudo_common_vars, "*") |
| |
| sources = [ |
| "tests/wrappers_c_test.cpp", |
| # TODO(https://fxbug.dev/42082846): see src/wrappers_cpp.cpp inclusion above. |
| #"tests/wrappers_cpp_test.cpp", |
| ] |
| } |
| |
| libc_test("gwp_asan-unittests") { |
| forward_variables_from(gwp_asan_common_vars, "*") |
| |
| sources = [ |
| "tests/alignment.cpp", |
| "tests/backtrace.cpp", |
| "tests/basic.cpp", |
| "tests/compression.cpp", |
| "tests/crash_handler_api.cpp", |
| |
| # TODO(kostyak): fork() based, see if it can apply to Fuchsia |
| #"tests/enable_disable.cpp", |
| "tests/harness.cpp", |
| "tests/harness.h", |
| "tests/iterate.cpp", |
| |
| # TODO(https://fxbug.dev/42144233): flaky due to TLS pollution |
| #"tests/late_init.cpp", |
| "tests/mutex_test.cpp", |
| "tests/never_allocated.cpp", |
| |
| # Exclude because signal handlers used in recoverable tests are unsupported |
| #"tests/recoverable.cpp" |
| "tests/slot_reuse.cpp", |
| "tests/thread_contention.cpp", |
| ] |
| |
| deps += [ |
| ":gwp_asan.testonly", |
| ":gwp_asan_test_printf", |
| ] |
| |
| # Suppress warnings from third party code |
| configs += [ "//build/config:Wno-extra-semi" ] |
| } |
| |
| source_set("gwp_asan_test_printf") { |
| testonly = true |
| include_dirs = [ "${gwp_asan}/.." ] |
| deps = [ ":gwp_asan.testonly" ] |
| sources = [ "gwp_asan_test_printf.cc" ] |
| } |