blob: f12634678a0acd4f81c79c989ac61afdc245762d [file] [log] [blame]
Colin Crossaf98f582021-05-12 17:27:32 -07001// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
18 "testing"
19
20 "android/soong/android"
21)
22
23var prepareForAsanTest = android.FixtureAddFile("asan/Android.bp", []byte(`
24 cc_library_shared {
25 name: "libclang_rt.asan-aarch64-android",
26 }
27
28 cc_library_shared {
29 name: "libclang_rt.asan-arm-android",
30 }
31`))
32
33func TestAsan(t *testing.T) {
34 bp := `
35 cc_binary {
36 name: "bin_with_asan",
37 host_supported: true,
38 shared_libs: [
39 "libshared",
40 "libasan",
41 ],
42 static_libs: [
43 "libstatic",
44 "libnoasan",
45 ],
46 sanitize: {
47 address: true,
48 }
49 }
50
51 cc_binary {
52 name: "bin_no_asan",
53 host_supported: true,
54 shared_libs: [
55 "libshared",
56 "libasan",
57 ],
58 static_libs: [
59 "libstatic",
60 "libnoasan",
61 ],
62 }
63
64 cc_library_shared {
65 name: "libshared",
66 host_supported: true,
67 shared_libs: ["libtransitive"],
68 }
69
70 cc_library_shared {
71 name: "libasan",
72 host_supported: true,
73 shared_libs: ["libtransitive"],
74 sanitize: {
75 address: true,
76 }
77 }
78
79 cc_library_shared {
80 name: "libtransitive",
81 host_supported: true,
82 }
83
84 cc_library_static {
85 name: "libstatic",
86 host_supported: true,
87 }
88
89 cc_library_static {
90 name: "libnoasan",
91 host_supported: true,
92 sanitize: {
93 address: false,
94 }
95 }
96 `
97
98 result := android.GroupFixturePreparers(
99 prepareForCcTest,
100 prepareForAsanTest,
101 ).RunTestWithBp(t, bp)
102
103 check := func(t *testing.T, result *android.TestResult, variant string) {
104 asanVariant := variant + "_asan"
105 sharedVariant := variant + "_shared"
106 sharedAsanVariant := sharedVariant + "_asan"
107 staticVariant := variant + "_static"
108 staticAsanVariant := staticVariant + "_asan"
109
110 // The binaries, one with asan and one without
111 binWithAsan := result.ModuleForTests("bin_with_asan", asanVariant)
112 binNoAsan := result.ModuleForTests("bin_no_asan", variant)
113
114 // Shared libraries that don't request asan
115 libShared := result.ModuleForTests("libshared", sharedVariant)
116 libTransitive := result.ModuleForTests("libtransitive", sharedVariant)
117
118 // Shared library that requests asan
119 libAsan := result.ModuleForTests("libasan", sharedAsanVariant)
120
121 // Static library that uses an asan variant for bin_with_asan and a non-asan variant
122 // for bin_no_asan.
123 libStaticAsanVariant := result.ModuleForTests("libstatic", staticAsanVariant)
124 libStaticNoAsanVariant := result.ModuleForTests("libstatic", staticVariant)
125
126 // Static library that never uses asan.
127 libNoAsan := result.ModuleForTests("libnoasan", staticVariant)
128
129 // expectSharedLinkDep verifies that the from module links against the to module as a
130 // shared library.
131 expectSharedLinkDep := func(from, to android.TestingModule) {
132 t.Helper()
133 fromLink := from.Description("link")
134 toLink := to.Description("strip")
135
136 if g, w := fromLink.OrderOnly.Strings(), toLink.Output.String(); !android.InList(w, g) {
137 t.Errorf("%s should link against %s, expected %q, got %q",
138 from.Module(), to.Module(), w, g)
139 }
140 }
141
142 // expectStaticLinkDep verifies that the from module links against the to module as a
143 // static library.
144 expectStaticLinkDep := func(from, to android.TestingModule) {
145 t.Helper()
146 fromLink := from.Description("link")
147 toLink := to.Description("static link")
148
149 if g, w := fromLink.Implicits.Strings(), toLink.Output.String(); !android.InList(w, g) {
150 t.Errorf("%s should link against %s, expected %q, got %q",
151 from.Module(), to.Module(), w, g)
152 }
153
154 }
155
156 // expectInstallDep verifies that the install rule of the from module depends on the
157 // install rule of the to module.
158 expectInstallDep := func(from, to android.TestingModule) {
159 t.Helper()
160 fromInstalled := from.Description("install")
161 toInstalled := to.Description("install")
162
163 // combine implicits and order-only dependencies, host uses implicit but device uses
164 // order-only.
165 got := append(fromInstalled.Implicits.Strings(), fromInstalled.OrderOnly.Strings()...)
166 want := toInstalled.Output.String()
167 if !android.InList(want, got) {
168 t.Errorf("%s installation should depend on %s, expected %q, got %q",
169 from.Module(), to.Module(), want, got)
170 }
171 }
172
173 expectSharedLinkDep(binWithAsan, libShared)
174 expectSharedLinkDep(binWithAsan, libAsan)
175 expectSharedLinkDep(libShared, libTransitive)
176 expectSharedLinkDep(libAsan, libTransitive)
177
178 expectStaticLinkDep(binWithAsan, libStaticAsanVariant)
179 expectStaticLinkDep(binWithAsan, libNoAsan)
180
181 expectInstallDep(binWithAsan, libShared)
182 expectInstallDep(binWithAsan, libAsan)
183 expectInstallDep(binWithAsan, libTransitive)
184 expectInstallDep(libShared, libTransitive)
185 expectInstallDep(libAsan, libTransitive)
186
187 expectSharedLinkDep(binNoAsan, libShared)
188 expectSharedLinkDep(binNoAsan, libAsan)
189 expectSharedLinkDep(libShared, libTransitive)
190 expectSharedLinkDep(libAsan, libTransitive)
191
192 expectStaticLinkDep(binNoAsan, libStaticNoAsanVariant)
193 expectStaticLinkDep(binNoAsan, libNoAsan)
194
195 expectInstallDep(binNoAsan, libShared)
196 expectInstallDep(binNoAsan, libAsan)
197 expectInstallDep(binNoAsan, libTransitive)
198 expectInstallDep(libShared, libTransitive)
199 expectInstallDep(libAsan, libTransitive)
200 }
201
202 t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) })
203 t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") })
204}