394 lines
12 KiB
Python
394 lines
12 KiB
Python
"""Copyright (C) 2022 The Android Open Source Project
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
"""
|
|
|
|
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
|
|
load(
|
|
":cc_toolchain_constants.bzl",
|
|
"generated_config_constants",
|
|
"generated_sanitizer_constants",
|
|
)
|
|
load(
|
|
"//build/bazel/rules/test_common:flags.bzl",
|
|
"action_flags_absent_for_mnemonic_test",
|
|
"action_flags_present_for_mnemonic_nonexclusive_test",
|
|
"action_flags_present_only_for_mnemonic_test",
|
|
)
|
|
|
|
compile_action_mnemonic = "CppCompile"
|
|
link_action_mnemonic = "CppLink"
|
|
|
|
def test_cfi_c_and_cpp_has_correct_flags():
|
|
name = "cfi_c_and_cpp_has_correct_flags"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["foo.c", "bar.cpp"],
|
|
features = ["android_cfi"],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
compile_test_name = name + "_compile_test"
|
|
action_flags_present_for_mnemonic_nonexclusive_test(
|
|
name = compile_test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic],
|
|
expected_flags = generated_sanitizer_constants.CfiCFlags +
|
|
[generated_sanitizer_constants.CfiCrossDsoFlag],
|
|
)
|
|
|
|
link_test_name = name + "_link_test"
|
|
action_flags_present_for_mnemonic_nonexclusive_test(
|
|
name = link_test_name,
|
|
target_under_test = name,
|
|
mnemonics = [link_action_mnemonic],
|
|
expected_flags = generated_sanitizer_constants.CfiLdFlags +
|
|
[generated_sanitizer_constants.CfiCrossDsoFlag],
|
|
)
|
|
|
|
return [
|
|
compile_test_name,
|
|
link_test_name,
|
|
]
|
|
|
|
def test_cfi_s_has_correct_flags():
|
|
name = "cfi_s_has_correct_flags"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["baz.s", "blah.S"],
|
|
features = ["android_cfi"],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
assemble_test_name = name + "_assemble_test"
|
|
action_flags_present_only_for_mnemonic_test(
|
|
name = assemble_test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic],
|
|
expected_flags = generated_sanitizer_constants.CfiAsFlags,
|
|
)
|
|
|
|
compile_flags_absent_test_name = name + "_compile_flags_absent_test"
|
|
action_flags_absent_for_mnemonic_test(
|
|
name = compile_flags_absent_test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic],
|
|
expected_absent_flags = generated_sanitizer_constants.CfiCFlags +
|
|
[generated_sanitizer_constants.CfiCrossDsoFlag],
|
|
)
|
|
|
|
return [
|
|
assemble_test_name,
|
|
compile_flags_absent_test_name,
|
|
]
|
|
|
|
def test_cross_dso_not_added_when_cfi_disabled():
|
|
name = "cross_dso_not_added_when_cfi_disabled"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["foo.c", "bar.cpp"],
|
|
features = ["android_cfi_cross_dso"],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
test_name = name + "_test"
|
|
action_flags_absent_for_mnemonic_test(
|
|
name = test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic, link_action_mnemonic],
|
|
expected_absent_flags = [generated_sanitizer_constants.CfiCrossDsoFlag],
|
|
)
|
|
|
|
return test_name
|
|
|
|
def test_cross_dso_not_added_when_static_binary():
|
|
name = "cross_dso_not_added_when_static_binary"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["foo.c", "bar.cpp"],
|
|
features = [
|
|
"android_cfi",
|
|
"static_executable",
|
|
"-dynamic_executable",
|
|
"android_cfi_cross_dso",
|
|
],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
android_test_name = name + "_android_test"
|
|
action_flags_absent_for_mnemonic_test(
|
|
name = android_test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic, link_action_mnemonic],
|
|
expected_absent_flags = [generated_sanitizer_constants.CfiCrossDsoFlag],
|
|
target_compatible_with = ["//build/bazel/platforms/os:android"],
|
|
)
|
|
|
|
linux_test_name = name + "_linux_test"
|
|
action_flags_absent_for_mnemonic_test(
|
|
name = linux_test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic, link_action_mnemonic],
|
|
expected_absent_flags = [generated_sanitizer_constants.CfiCrossDsoFlag],
|
|
target_compatible_with = ["//build/bazel/platforms/os:linux_glibc"],
|
|
)
|
|
|
|
return [
|
|
android_test_name,
|
|
linux_test_name,
|
|
]
|
|
|
|
def test_cfi_assembly_support_has_correct_flags():
|
|
name = "cfi_assembly_support_has_correct_flags"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["foo.c", "bar.cpp"],
|
|
features = [
|
|
"android_cfi",
|
|
"android_cfi_assembly_support",
|
|
],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
test_name = name + "_test"
|
|
action_flags_present_only_for_mnemonic_test(
|
|
name = test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic],
|
|
expected_flags = [generated_sanitizer_constants.CfiAssemblySupportFlag],
|
|
)
|
|
|
|
return test_name
|
|
|
|
def test_cfi_assembly_support_does_not_add_flags_for_s():
|
|
name = "cfi_assembly_support_does_not_add_flags_for_s"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["baz.s", "blah.S"],
|
|
features = [
|
|
"android_cfi",
|
|
"android_cfi_assembly_support",
|
|
],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
test_name = name + "_test"
|
|
action_flags_absent_for_mnemonic_test(
|
|
name = test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic],
|
|
expected_absent_flags = [
|
|
generated_sanitizer_constants.CfiAssemblySupportFlag,
|
|
],
|
|
)
|
|
|
|
return test_name
|
|
|
|
def test_cfi_exports_map_has_correct_flags():
|
|
name = "cfi_exports_map_has_correct_flags"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["foo.c", "bar.cpp"],
|
|
features = [
|
|
"android_cfi",
|
|
"android_cfi_exports_map",
|
|
],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
test_name = name + "_test"
|
|
action_flags_present_only_for_mnemonic_test(
|
|
name = test_name,
|
|
target_under_test = name,
|
|
mnemonics = [link_action_mnemonic],
|
|
expected_flags = [
|
|
generated_config_constants.VersionScriptFlagPrefix +
|
|
generated_sanitizer_constants.CfiExportsMapPath +
|
|
"/" +
|
|
generated_sanitizer_constants.CfiExportsMapFilename,
|
|
],
|
|
)
|
|
|
|
return test_name
|
|
|
|
def test_cfi_cross_dso_has_correct_flags():
|
|
name = "cfi_cross_dso_has_correct_flags"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["foo.c", "bar.cpp"],
|
|
features = [
|
|
"android_cfi",
|
|
"android_cfi_cross_dso",
|
|
],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
test_name = name + "_test"
|
|
action_flags_present_only_for_mnemonic_test(
|
|
name = test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic, link_action_mnemonic],
|
|
expected_flags = [generated_sanitizer_constants.CfiCrossDsoFlag],
|
|
)
|
|
|
|
return test_name
|
|
|
|
def test_cfi_cross_dso_does_not_add_flags_for_s():
|
|
name = "cfi_cross_dso_does_not_add_flags_for_s"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["baz.s", "blah.S"],
|
|
features = [
|
|
"android_cfi",
|
|
"android_cfi_cross_dso",
|
|
],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
test_name = name + "_test"
|
|
action_flags_absent_for_mnemonic_test(
|
|
name = test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic],
|
|
expected_absent_flags = [generated_sanitizer_constants.CfiCrossDsoFlag],
|
|
)
|
|
|
|
return test_name
|
|
|
|
def test_cfi_implies_lto():
|
|
name = "cfi_implies_lto"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["foo.c", "bar.cpp"],
|
|
features = ["android_cfi"],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
test_name = name + "_test"
|
|
action_flags_present_for_mnemonic_nonexclusive_test(
|
|
name = test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic],
|
|
expected_flags = ["-flto=thin"],
|
|
)
|
|
|
|
return test_name
|
|
|
|
def test_cfi_implies_vis_default_if_not_hidden():
|
|
name = "cfi_implies_vis_default_if_not_hidden"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["foo.c", "bar.cpp"],
|
|
features = ["android_cfi"],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
test_name = name + "_test"
|
|
action_flags_present_only_for_mnemonic_test(
|
|
name = test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic],
|
|
expected_flags = ["-fvisibility=default"],
|
|
)
|
|
|
|
return test_name
|
|
|
|
def test_cfi_does_not_add_vis_default_if_hidden():
|
|
name = "cfi_does_not_add_vis_default_if_hidden"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["foo.c", "bar.cpp"],
|
|
features = ["android_cfi", "visibility_hidden"],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
test_name = name + "_test"
|
|
action_flags_absent_for_mnemonic_test(
|
|
name = test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic],
|
|
expected_absent_flags = ["-fvisibility=default"],
|
|
)
|
|
|
|
return test_name
|
|
|
|
def test_cfi_and_arm_uses_thumb():
|
|
name = "cfi_and_arm_uses_thumb"
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = ["foo.c", "bar.cpp"],
|
|
features = ["android_cfi"],
|
|
tags = ["manual"],
|
|
)
|
|
|
|
test_name = name + "_test"
|
|
action_flags_present_for_mnemonic_nonexclusive_test(
|
|
name = test_name,
|
|
target_under_test = name,
|
|
mnemonics = [compile_action_mnemonic],
|
|
expected_flags = generated_config_constants.ArmThumbCflags,
|
|
target_compatible_with = [
|
|
"//build/bazel/platforms/arch:arm",
|
|
],
|
|
)
|
|
|
|
return test_name
|
|
|
|
# TODO(b/274924237): Uncomment after Darwin and Windows have toolchains
|
|
#def test_cfi_absent_on_unsupported_oses():
|
|
# name = "cfi_absent_on_unsupported_oses"
|
|
# native.cc_binary(
|
|
# name = name,
|
|
# srcs = ["foo.c", "bar.cpp"],
|
|
# features = ["android_cfi"],
|
|
# tags = ["manual"],
|
|
# )
|
|
#
|
|
# test_name = name + "_test"
|
|
# action_flags_absent_for_mnemonic_test(
|
|
# name = test_name,
|
|
# target_under_test = name,
|
|
# mnemonics = [compile_action_mnemonic],
|
|
# expected_absent_flags = generated_sanitizer_constants.CfiCFlags,
|
|
# target_compatible_with = [
|
|
# "//build/bazel/platforms/os:linux_musl",
|
|
# "//build/bazel/platforms/os:darwin",
|
|
# "//build/bazel/platforms/os:windows",
|
|
# ]
|
|
# )
|
|
#
|
|
# return test_name
|
|
|
|
def cc_toolchain_features_cfi_test_suite(name):
|
|
individual_tests = [
|
|
test_cross_dso_not_added_when_cfi_disabled(),
|
|
test_cfi_assembly_support_has_correct_flags(),
|
|
test_cfi_assembly_support_does_not_add_flags_for_s(),
|
|
test_cfi_exports_map_has_correct_flags(),
|
|
test_cfi_cross_dso_has_correct_flags(),
|
|
test_cfi_cross_dso_does_not_add_flags_for_s(),
|
|
test_cfi_implies_lto(),
|
|
test_cfi_implies_vis_default_if_not_hidden(),
|
|
test_cfi_does_not_add_vis_default_if_hidden(),
|
|
test_cfi_and_arm_uses_thumb(),
|
|
# TODO(b/274924237): Uncomment after Darwin and Windows have toolchains
|
|
# test_cfi_absent_on_unsupported_oses(),
|
|
]
|
|
native.test_suite(
|
|
name = name,
|
|
tests = individual_tests +
|
|
test_cfi_c_and_cpp_has_correct_flags() +
|
|
test_cfi_s_has_correct_flags() +
|
|
test_cross_dso_not_added_when_static_binary(),
|
|
)
|