1// 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} 205