Skip to content

Commit fdc5662

Browse files
committed
Build libc++ with sanitizers enabled
1 parent bdbeec8 commit fdc5662

5 files changed

Lines changed: 57 additions & 5 deletions

File tree

3rd_party/llvm-project/x.x/libcxx/libcxx.BUILD.bazel

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
44
load("@bazel_skylib//rules:write_file.bzl", "write_file")
55
load("@llvm//3rd_party/llvm-project/21.x/libcxx:libcxx_headers.bzl", "LIBCXX_HEADERS_FILES_21")
66
load("@llvm//3rd_party/llvm-project/22.x/libcxx:libcxx_headers.bzl", "LIBCXX_HEADERS_FILES_22")
7-
load("@llvm//toolchain/runtimes:cc_runtime_shared_library.bzl", "cc_runtime_stage1_shared_library")
8-
load("@llvm//toolchain/runtimes:cc_runtime_static_library.bzl", "cc_runtime_stage0_static_library")
7+
load("@llvm//toolchain/runtimes:cc_runtime_shared_library.bzl", "cc_runtime_stage1_sanitized_shared_library")
8+
load("@llvm//toolchain/runtimes:cc_runtime_static_library.bzl", "cc_runtime_stage0_sanitized_static_library")
99
load("@llvm-project//:vars.bzl", "LLVM_VERSION_MAJOR")
1010
load("@rules_cc//cc:cc_library.bzl", "cc_library")
1111

@@ -40,6 +40,14 @@ _CONFIG_SITE_NO_MUSL_LINES = [
4040
"#define _LIBCPP_HAS_MUSL_LIBC 0",
4141
]
4242

43+
_CONFIG_SITE_ASAN_LINES = [
44+
"#define _LIBCPP_INSTRUMENTED_WITH_ASAN 1",
45+
]
46+
47+
_CONFIG_SITE_NO_ASAN_LINES = [
48+
"#define _LIBCPP_INSTRUMENTED_WITH_ASAN 0",
49+
]
50+
4351
_CONFIG_SITE_THREAD_API_WIN32_LINES = [
4452
"#define _LIBCPP_HAS_THREAD_API_PTHREAD 0",
4553
"#define _LIBCPP_HAS_THREAD_API_WIN32 1",
@@ -74,7 +82,6 @@ _CONFIG_SITE_GENERIC_LINES = [
7482
"#define _LIBCPP_HAS_STD_MODULES 0",
7583
"#define _LIBCPP_HAS_TIME_ZONE_DATABASE 1",
7684
"#define _LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS 0",
77-
"#define _LIBCPP_INSTRUMENTED_WITH_ASAN 0",
7885
"",
7986
"#define _LIBCPP_PSTL_BACKEND_SERIAL",
8087
"// #define _LIBCPP_PSTL_BACKEND_STD_THREAD",
@@ -110,6 +117,10 @@ write_file(
110117
select({
111118
"@platforms//os:windows": _CONFIG_SITE_THREAD_API_WIN32_LINES,
112119
"//conditions:default": _CONFIG_SITE_THREAD_API_PTHREAD_LINES,
120+
}) +
121+
select({
122+
"@llvm//config:asan_enabled": _CONFIG_SITE_ASAN_LINES,
123+
"//conditions:default": _CONFIG_SITE_NO_ASAN_LINES,
113124
}),
114125
visibility = ["//visibility:public"],
115126
)
@@ -349,15 +360,15 @@ cc_library(
349360
],
350361
)
351362

352-
cc_runtime_stage0_static_library(
363+
cc_runtime_stage0_sanitized_static_library(
353364
name = "libcxx.static",
354365
visibility = ["//visibility:public"],
355366
deps = [
356367
":libcxx",
357368
],
358369
)
359370

360-
cc_runtime_stage1_shared_library(
371+
cc_runtime_stage1_sanitized_shared_library(
361372
name = "libcxx.shared",
362373
shared_lib_name = "libc++.so.1",
363374
user_link_flags = [

e2e/rules_cc/BUILD.bazel

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,17 @@ asan_cc_binary(
770770
}),
771771
)
772772

773+
exec_test(
774+
name = "asan_libcxx_container_overflow_test",
775+
srcs = ["asan_libcxx_container_overflow.cc"],
776+
linkopts = ["-Wl,--icf=none"],
777+
rule = asan_cc_binary,
778+
target_compatible_with = select({
779+
"@platforms//os:linux": [],
780+
"//conditions:default": ["@platforms//:incompatible"],
781+
}),
782+
)
783+
773784
exec_test(
774785
name = "asan_output_test",
775786
srcs = ["asan_output_test.sh"],
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <sanitizer/asan_interface.h>
2+
3+
#include <cstdio>
4+
#include <string>
5+
6+
int main() {
7+
std::string value;
8+
if (!__asan_address_is_poisoned(value.data() + 1)) {
9+
std::fprintf(stderr, "std::string ASan annotations are disabled\n");
10+
return 1;
11+
}
12+
13+
value.push_back('x');
14+
15+
// push_back must unpoison the new null terminator. If libc++ is not built
16+
// with ASan, reading the valid null terminator reports container-overflow.
17+
volatile char terminator = value.c_str()[value.size()];
18+
return terminator == '\0' ? 0 : 1;
19+
}

toolchain/runtimes/cc_runtime_shared_library.bzl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,11 @@ _builder = with_cfg(
1010

1111
cc_runtime_stage0_shared_library, _cc_stage0_shared_library_internal = configure_builder_for_runtimes(_builder.clone(), "stage0", "dynamic").build()
1212
cc_runtime_stage1_shared_library, _cc_stage1_shared_library_internal = configure_builder_for_runtimes(_builder.clone(), "stage1", "dynamic").build()
13+
cc_runtime_stage1_sanitized_shared_library, _cc_stage1_sanitized_shared_library_internal = configure_builder_for_runtimes(
14+
_builder.clone(),
15+
"stage1",
16+
"dynamic",
17+
sanitizers = True,
18+
).build()
1319
cc_runtime_stage2_shared_library, _cc_stage2_shared_library_internal = configure_builder_for_runtimes(_builder.clone(), "stage2", "dynamic").build()
1420
cc_runtime_stage3_shared_library, _cc_stage3_shared_library_internal = configure_builder_for_runtimes(_builder.clone(), "stage3", "dynamic").build()

toolchain/runtimes/cc_runtime_static_library.bzl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ _builder = with_cfg(
99
# NOTE: runtime static libraries do not have >stage0 dependencies.
1010
# Those are only needed for shared libraries.
1111
cc_runtime_stage0_static_library, _cc_stage0_static_library_internal = configure_builder_for_runtimes(_builder.clone(), "stage0").build()
12+
cc_runtime_stage0_sanitized_static_library, _cc_stage0_sanitized_static_library_internal = configure_builder_for_runtimes(
13+
_builder.clone(),
14+
"stage0",
15+
sanitizers = True,
16+
).build()

0 commit comments

Comments
 (0)