1 // Copyright (C) 2016 The Android Open Source Project 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 15 package art 16 17 import ( 18 "android/soong/android" 19 "android/soong/cc" 20 "fmt" 21 "sync" 22 ) 23 24 var supportedArches = []string{"arm", "arm64", "mips", "mips64", "x86", "x86_64"} 25 26 func globalFlags(ctx android.BaseContext) ([]string, []string) { 27 var cflags []string 28 var asflags []string 29 30 opt := envDefault(ctx, "ART_NDEBUG_OPT_FLAG", "-O3") 31 cflags = append(cflags, opt) 32 33 tlab := false 34 35 gcType := envDefault(ctx, "ART_DEFAULT_GC_TYPE", "CMS") 36 37 if envTrue(ctx, "ART_TEST_DEBUG_GC") { 38 gcType = "SS" 39 tlab = true 40 } 41 42 cflags = append(cflags, "-DART_DEFAULT_GC_TYPE_IS_"+gcType) 43 if tlab { 44 cflags = append(cflags, "-DART_USE_TLAB=1") 45 } 46 47 if !envFalse(ctx, "ART_ENABLE_VDEX") { 48 cflags = append(cflags, "-DART_ENABLE_VDEX") 49 } 50 51 imtSize := envDefault(ctx, "ART_IMT_SIZE", "43") 52 cflags = append(cflags, "-DIMT_SIZE="+imtSize) 53 54 if envTrue(ctx, "ART_HEAP_POISONING") { 55 cflags = append(cflags, "-DART_HEAP_POISONING=1") 56 asflags = append(asflags, "-DART_HEAP_POISONING=1") 57 } 58 59 if !envFalse(ctx, "ART_USE_READ_BARRIER") && ctx.AConfig().ArtUseReadBarrier() { 60 // Used to change the read barrier type. Valid values are BAKER, BROOKS, 61 // TABLELOOKUP. The default is BAKER. 62 barrierType := envDefault(ctx, "ART_READ_BARRIER_TYPE", "BAKER") 63 cflags = append(cflags, 64 "-DART_USE_READ_BARRIER=1", 65 "-DART_READ_BARRIER_TYPE_IS_"+barrierType+"=1") 66 asflags = append(asflags, 67 "-DART_USE_READ_BARRIER=1", 68 "-DART_READ_BARRIER_TYPE_IS_"+barrierType+"=1") 69 } 70 71 // We need larger stack overflow guards for ASAN, as the compiled code will have 72 // larger frame sizes. For simplicity, just use global not-target-specific cflags. 73 // Note: We increase this for both debug and non-debug, as the overflow gap will 74 // be compiled into managed code. We always preopt (and build core images) with 75 // the debug version. So make the gap consistent (and adjust for the worst). 76 if len(ctx.AConfig().SanitizeDevice()) > 0 || len(ctx.AConfig().SanitizeHost()) > 0 { 77 cflags = append(cflags, 78 "-DART_STACK_OVERFLOW_GAP_arm=8192", 79 "-DART_STACK_OVERFLOW_GAP_arm64=8192", 80 "-DART_STACK_OVERFLOW_GAP_mips=16384", 81 "-DART_STACK_OVERFLOW_GAP_mips64=16384", 82 "-DART_STACK_OVERFLOW_GAP_x86=16384", 83 "-DART_STACK_OVERFLOW_GAP_x86_64=20480") 84 } else { 85 cflags = append(cflags, 86 "-DART_STACK_OVERFLOW_GAP_arm=8192", 87 "-DART_STACK_OVERFLOW_GAP_arm64=8192", 88 "-DART_STACK_OVERFLOW_GAP_mips=16384", 89 "-DART_STACK_OVERFLOW_GAP_mips64=16384", 90 "-DART_STACK_OVERFLOW_GAP_x86=8192", 91 "-DART_STACK_OVERFLOW_GAP_x86_64=8192") 92 } 93 94 if envTrue(ctx, "ART_ENABLE_ADDRESS_SANITIZER") { 95 // Used to enable full sanitization, i.e., user poisoning, under ASAN. 96 cflags = append(cflags, "-DART_ENABLE_ADDRESS_SANITIZER=1") 97 asflags = append(asflags, "-DART_ENABLE_ADDRESS_SANITIZER=1") 98 } 99 100 return cflags, asflags 101 } 102 103 func debugFlags(ctx android.BaseContext) []string { 104 var cflags []string 105 106 opt := envDefault(ctx, "ART_DEBUG_OPT_FLAG", "-O2") 107 cflags = append(cflags, opt) 108 109 return cflags 110 } 111 112 func deviceFlags(ctx android.BaseContext) []string { 113 var cflags []string 114 deviceFrameSizeLimit := 1736 115 if len(ctx.AConfig().SanitizeDevice()) > 0 { 116 deviceFrameSizeLimit = 7400 117 } 118 cflags = append(cflags, 119 fmt.Sprintf("-Wframe-larger-than=%d", deviceFrameSizeLimit), 120 fmt.Sprintf("-DART_FRAME_SIZE_LIMIT=%d", deviceFrameSizeLimit), 121 ) 122 123 cflags = append(cflags, "-DART_BASE_ADDRESS="+ctx.AConfig().LibartImgDeviceBaseAddress()) 124 if envTrue(ctx, "ART_TARGET_LINUX") { 125 cflags = append(cflags, "-DART_TARGET_LINUX") 126 } else { 127 cflags = append(cflags, "-DART_TARGET_ANDROID") 128 } 129 minDelta := envDefault(ctx, "LIBART_IMG_TARGET_MIN_BASE_ADDRESS_DELTA", "-0x1000000") 130 maxDelta := envDefault(ctx, "LIBART_IMG_TARGET_MAX_BASE_ADDRESS_DELTA", "0x1000000") 131 cflags = append(cflags, "-DART_BASE_ADDRESS_MIN_DELTA="+minDelta) 132 cflags = append(cflags, "-DART_BASE_ADDRESS_MAX_DELTA="+maxDelta) 133 134 return cflags 135 } 136 137 func hostFlags(ctx android.BaseContext) []string { 138 var cflags []string 139 hostFrameSizeLimit := 1736 140 if len(ctx.AConfig().SanitizeHost()) > 0 { 141 // art/test/137-cfi/cfi.cc 142 // error: stack frame size of 1944 bytes in function 'Java_Main_unwindInProcess' 143 hostFrameSizeLimit = 6400 144 } 145 cflags = append(cflags, 146 fmt.Sprintf("-Wframe-larger-than=%d", hostFrameSizeLimit), 147 fmt.Sprintf("-DART_FRAME_SIZE_LIMIT=%d", hostFrameSizeLimit), 148 ) 149 150 cflags = append(cflags, "-DART_BASE_ADDRESS="+ctx.AConfig().LibartImgHostBaseAddress()) 151 minDelta := envDefault(ctx, "LIBART_IMG_HOST_MIN_BASE_ADDRESS_DELTA", "-0x1000000") 152 maxDelta := envDefault(ctx, "LIBART_IMG_HOST_MAX_BASE_ADDRESS_DELTA", "0x1000000") 153 cflags = append(cflags, "-DART_BASE_ADDRESS_MIN_DELTA="+minDelta) 154 cflags = append(cflags, "-DART_BASE_ADDRESS_MAX_DELTA="+maxDelta) 155 156 return cflags 157 } 158 159 func globalDefaults(ctx android.LoadHookContext) { 160 type props struct { 161 Target struct { 162 Android struct { 163 Cflags []string 164 } 165 Host struct { 166 Cflags []string 167 } 168 } 169 Cflags []string 170 Asflags []string 171 Sanitize struct { 172 Recover []string 173 } 174 } 175 176 p := &props{} 177 p.Cflags, p.Asflags = globalFlags(ctx) 178 p.Target.Android.Cflags = deviceFlags(ctx) 179 p.Target.Host.Cflags = hostFlags(ctx) 180 181 if envTrue(ctx, "ART_DEX_FILE_ACCESS_TRACKING") { 182 p.Cflags = append(p.Cflags, "-DART_DEX_FILE_ACCESS_TRACKING") 183 p.Sanitize.Recover = []string{ 184 "address", 185 } 186 } 187 188 ctx.AppendProperties(p) 189 } 190 191 func debugDefaults(ctx android.LoadHookContext) { 192 type props struct { 193 Cflags []string 194 } 195 196 p := &props{} 197 p.Cflags = debugFlags(ctx) 198 ctx.AppendProperties(p) 199 } 200 201 func customLinker(ctx android.LoadHookContext) { 202 linker := envDefault(ctx, "CUSTOM_TARGET_LINKER", "") 203 if linker != "" { 204 type props struct { 205 DynamicLinker string 206 } 207 208 p := &props{} 209 p.DynamicLinker = linker 210 ctx.AppendProperties(p) 211 } 212 } 213 214 func prefer32Bit(ctx android.LoadHookContext) { 215 if envTrue(ctx, "HOST_PREFER_32_BIT") { 216 type props struct { 217 Target struct { 218 Host struct { 219 Compile_multilib string 220 } 221 } 222 } 223 224 p := &props{} 225 p.Target.Host.Compile_multilib = "prefer32" 226 ctx.AppendProperties(p) 227 } 228 } 229 230 func testMap(config android.Config) map[string][]string { 231 return config.Once("artTests", func() interface{} { 232 return make(map[string][]string) 233 }).(map[string][]string) 234 } 235 236 func testInstall(ctx android.InstallHookContext) { 237 testMap := testMap(ctx.AConfig()) 238 239 var name string 240 if ctx.Host() { 241 name = "host_" 242 } else { 243 name = "device_" 244 } 245 name += ctx.Arch().ArchType.String() + "_" + ctx.ModuleName() 246 247 artTestMutex.Lock() 248 defer artTestMutex.Unlock() 249 250 tests := testMap[name] 251 tests = append(tests, ctx.Path().RelPathString()) 252 testMap[name] = tests 253 } 254 255 var artTestMutex sync.Mutex 256 257 func init() { 258 android.RegisterModuleType("art_cc_library", artLibrary) 259 android.RegisterModuleType("art_cc_binary", artBinary) 260 android.RegisterModuleType("art_cc_test", artTest) 261 android.RegisterModuleType("art_cc_test_library", artTestLibrary) 262 android.RegisterModuleType("art_cc_defaults", artDefaultsFactory) 263 android.RegisterModuleType("art_global_defaults", artGlobalDefaultsFactory) 264 android.RegisterModuleType("art_debug_defaults", artDebugDefaultsFactory) 265 } 266 267 func artGlobalDefaultsFactory() android.Module { 268 module := artDefaultsFactory() 269 android.AddLoadHook(module, globalDefaults) 270 271 return module 272 } 273 274 func artDebugDefaultsFactory() android.Module { 275 module := artDefaultsFactory() 276 android.AddLoadHook(module, debugDefaults) 277 278 return module 279 } 280 281 func artDefaultsFactory() android.Module { 282 c := &codegenProperties{} 283 module := cc.DefaultsFactory(c) 284 android.AddLoadHook(module, func(ctx android.LoadHookContext) { codegen(ctx, c, true) }) 285 286 return module 287 } 288 289 func artLibrary() android.Module { 290 library, _ := cc.NewLibrary(android.HostAndDeviceSupported) 291 module := library.Init() 292 293 installCodegenCustomizer(module, true) 294 295 return module 296 } 297 298 func artBinary() android.Module { 299 binary, _ := cc.NewBinary(android.HostAndDeviceSupported) 300 module := binary.Init() 301 302 android.AddLoadHook(module, customLinker) 303 android.AddLoadHook(module, prefer32Bit) 304 return module 305 } 306 307 func artTest() android.Module { 308 test := cc.NewTest(android.HostAndDeviceSupported) 309 module := test.Init() 310 311 installCodegenCustomizer(module, false) 312 313 android.AddLoadHook(module, customLinker) 314 android.AddLoadHook(module, prefer32Bit) 315 android.AddInstallHook(module, testInstall) 316 return module 317 } 318 319 func artTestLibrary() android.Module { 320 test := cc.NewTestLibrary(android.HostAndDeviceSupported) 321 module := test.Init() 322 323 installCodegenCustomizer(module, false) 324 325 android.AddLoadHook(module, prefer32Bit) 326 android.AddInstallHook(module, testInstall) 327 return module 328 } 329 330 func envDefault(ctx android.BaseContext, key string, defaultValue string) string { 331 ret := ctx.AConfig().Getenv(key) 332 if ret == "" { 333 return defaultValue 334 } 335 return ret 336 } 337 338 func envTrue(ctx android.BaseContext, key string) bool { 339 return ctx.AConfig().Getenv(key) == "true" 340 } 341 342 func envFalse(ctx android.BaseContext, key string) bool { 343 return ctx.AConfig().Getenv(key) == "false" 344 } 345