1"""Copyright (C) 2022 The Android Open Source Project
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7     http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14"""
15
16load("//build/bazel/rules/cc:cc_binary.bzl", "cc_binary")
17load(
18    "//build/bazel/rules/test_common:flags.bzl",
19    "action_flags_absent_for_mnemonic_test",
20    "action_flags_present_only_for_mnemonic_test",
21)
22
23_SHT_RELR_ARGS = ["-Wl,--pack-dyn-relocs=android+relr"]
24_ANDROID_RELR_ARGS = ["-Wl,--pack-dyn-relocs=android+relr", "-Wl,--use-android-relr-tags"]
25_RELR_PACKER_ARGS = ["-Wl,--pack-dyn-relocs=android"]
26_DISABLE_RELOC_ARGS = ["-Wl,--pack-dyn-relocs=none"]
27
28# Include these different file types to make sure that all actions types are
29# triggered
30test_srcs = [
31    "foo.cpp",
32    "bar.c",
33    "baz.s",
34    "blah.S",
35]
36
37def _create_relr_targets(name, sdk_version, extra_target_features = []):
38    name = "relocation_features_" + name
39    cc_binary(
40        name = name,
41        srcs = test_srcs,
42        min_sdk_version = sdk_version,
43        features = extra_target_features,
44        tags = ["manual"],
45    )
46    return name
47
48def _test_relocation_feature_flags(*, name, sdk_version, flags):
49    name = _create_relr_targets(name, sdk_version)
50    android_test_name = name + "_android_test"
51    linux_test_name = name + "_linux_test"
52    target_under_test = name + "_unstripped"
53    action_flags_present_only_for_mnemonic_test(
54        name = android_test_name,
55        target_under_test = target_under_test,
56        mnemonics = ["CppLink"],
57        expected_flags = flags,
58        target_compatible_with = [
59            "//build/bazel_common_rules/platforms/os:android",
60        ],
61    )
62    action_flags_absent_for_mnemonic_test(
63        name = linux_test_name,
64        target_under_test = target_under_test,
65        mnemonics = ["CppLink"],
66        expected_absent_flags = flags,
67        target_compatible_with = [
68            "//build/bazel_common_rules/platforms/os:linux",
69        ],
70    )
71    return [
72        android_test_name,
73        linux_test_name,
74    ]
75
76def _test_no_relocation_features(*, name, sdk_version, extra_target_features = []):
77    name = _create_relr_targets(name, sdk_version, extra_target_features)
78    android_test_name = name + "_android_test"
79    linux_test_name = name + "_linux_test"
80    target_under_test = name + "_unstripped"
81    action_flags_absent_for_mnemonic_test(
82        name = android_test_name,
83        target_under_test = target_under_test,
84        mnemonics = ["CppLink"],
85        expected_absent_flags = _SHT_RELR_ARGS + _ANDROID_RELR_ARGS + _RELR_PACKER_ARGS,
86        target_compatible_with = [
87            "//build/bazel_common_rules/platforms/os:android",
88        ],
89    )
90    action_flags_absent_for_mnemonic_test(
91        name = linux_test_name,
92        target_under_test = target_under_test,
93        mnemonics = ["CppLink"],
94        expected_absent_flags = _SHT_RELR_ARGS + _ANDROID_RELR_ARGS + _RELR_PACKER_ARGS,
95        target_compatible_with = [
96            "//build/bazel_common_rules/platforms/os:linux",
97        ],
98    )
99    return [
100        android_test_name,
101        linux_test_name,
102    ]
103
104def _test_disable_relocation_features(*, name, sdk_version, extra_target_features):
105    name = _create_relr_targets(name, sdk_version, extra_target_features)
106    android_test_name = name + "_android_test"
107    linux_test_name = name + "_linux_test"
108    target_under_test = name + "_unstripped"
109    action_flags_present_only_for_mnemonic_test(
110        name = android_test_name,
111        target_under_test = target_under_test,
112        mnemonics = ["CppLink"],
113        expected_flags = _DISABLE_RELOC_ARGS,
114        target_compatible_with = [
115            "//build/bazel_common_rules/platforms/os:android",
116        ],
117    )
118    action_flags_present_only_for_mnemonic_test(
119        name = linux_test_name,
120        target_under_test = target_under_test,
121        mnemonics = ["CppLink"],
122        expected_flags = _DISABLE_RELOC_ARGS,
123        target_compatible_with = [
124            "//build/bazel_common_rules/platforms/os:linux",
125        ],
126    )
127    return [
128        android_test_name,
129        linux_test_name,
130    ] + _test_no_relocation_features(
131        name = name + "_no_relr_features",
132        sdk_version = sdk_version,
133        extra_target_features = extra_target_features,
134    )
135
136def _generate_relocation_feature_tests():
137    return (
138        _test_relocation_feature_flags(
139            name = "sdk_version_30",
140            sdk_version = "30",
141            flags = _SHT_RELR_ARGS,
142        ) +
143        _test_relocation_feature_flags(
144            name = "sdk_version_29",
145            # this sdk_version is too low for sht_relr
146            sdk_version = "29",
147            flags = _ANDROID_RELR_ARGS,
148        ) +
149        _test_relocation_feature_flags(
150            name = "sdk_version_27",
151            # this sdk_version is too low for android_relr
152            sdk_version = "27",
153            flags = _RELR_PACKER_ARGS,
154        ) +
155        _test_relocation_feature_flags(
156            name = "sdk_version_24",
157            sdk_version = "24",
158            flags = _RELR_PACKER_ARGS,
159        ) +
160        _test_no_relocation_features(
161            name = "sdk_version_22",
162            # this sdk_version is too low for relocation_packer
163            sdk_version = "22",
164        ) +
165        _test_disable_relocation_features(
166            name = "sdk_version_30_disable_pack_relocations",
167            sdk_version = "30",
168            extra_target_features = ["disable_pack_relocations"],
169        ) +
170        _test_disable_relocation_features(
171            name = "sdk_version_29_disable_pack_relocations",
172            sdk_version = "29",
173            extra_target_features = ["disable_pack_relocations"],
174        ) +
175        _test_disable_relocation_features(
176            name = "sdk_version_27_disable_pack_relocations",
177            sdk_version = "27",
178            extra_target_features = ["disable_pack_relocations"],
179        ) +
180        _test_disable_relocation_features(
181            name = "sdk_version_24_disable_pack_relocations",
182            sdk_version = "24",
183            extra_target_features = ["disable_pack_relocations"],
184        ) +
185        _test_disable_relocation_features(
186            name = "sdk_version_22_disable_pack_relocations",
187            sdk_version = "22",
188            extra_target_features = ["disable_pack_relocations"],
189        )
190    )
191
192def cc_toolchain_features_pack_relocation_test_suite(name):
193    native.test_suite(
194        name = name,
195        tests = _generate_relocation_feature_tests(),
196    )
197