• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	"fmt"
19 	"log"
20 	"sync"
21 
22 	"github.com/google/blueprint/proptools"
23 
24 	"android/soong/android"
25 	"android/soong/apex"
26 	"android/soong/cc"
27 )
28 
29 var supportedArches = []string{"arm", "arm64", "x86", "x86_64"}
30 
31 func globalFlags(ctx android.LoadHookContext) ([]string, []string) {
32 	var cflags []string
33 	var asflags []string
34 
35 	opt := ctx.Config().GetenvWithDefault("ART_NDEBUG_OPT_FLAG", "-O3")
36 	cflags = append(cflags, opt)
37 
38 	tlab := false
39 
40 	gcType := ctx.Config().GetenvWithDefault("ART_DEFAULT_GC_TYPE", "CMS")
41 
42 	if ctx.Config().IsEnvTrue("ART_TEST_DEBUG_GC") {
43 		gcType = "SS"
44 		tlab = true
45 	}
46 
47 	cflags = append(cflags, "-DART_DEFAULT_GC_TYPE_IS_"+gcType)
48 	if tlab {
49 		cflags = append(cflags, "-DART_USE_TLAB=1")
50 	}
51 
52 	imtSize := ctx.Config().GetenvWithDefault("ART_IMT_SIZE", "43")
53 	cflags = append(cflags, "-DIMT_SIZE="+imtSize)
54 
55 	if ctx.Config().IsEnvTrue("ART_HEAP_POISONING") {
56 		cflags = append(cflags, "-DART_HEAP_POISONING=1")
57 		asflags = append(asflags, "-DART_HEAP_POISONING=1")
58 	}
59 	if ctx.Config().IsEnvTrue("ART_USE_CXX_INTERPRETER") {
60 		cflags = append(cflags, "-DART_USE_CXX_INTERPRETER=1")
61 	}
62 
63 	if !ctx.Config().IsEnvFalse("ART_USE_READ_BARRIER") && ctx.Config().ArtUseReadBarrier() {
64 		// Used to change the read barrier type. Valid values are BAKER, BROOKS,
65 		// TABLELOOKUP. The default is BAKER.
66 		barrierType := ctx.Config().GetenvWithDefault("ART_READ_BARRIER_TYPE", "BAKER")
67 		cflags = append(cflags,
68 			"-DART_USE_READ_BARRIER=1",
69 			"-DART_READ_BARRIER_TYPE_IS_"+barrierType+"=1")
70 		asflags = append(asflags,
71 			"-DART_USE_READ_BARRIER=1",
72 			"-DART_READ_BARRIER_TYPE_IS_"+barrierType+"=1")
73 	}
74 
75 	if !ctx.Config().IsEnvFalse("ART_USE_GENERATIONAL_CC") {
76 		cflags = append(cflags, "-DART_USE_GENERATIONAL_CC=1")
77 	}
78 
79 	cdexLevel := ctx.Config().GetenvWithDefault("ART_DEFAULT_COMPACT_DEX_LEVEL", "fast")
80 	cflags = append(cflags, "-DART_DEFAULT_COMPACT_DEX_LEVEL="+cdexLevel)
81 
82 	// We need larger stack overflow guards for ASAN, as the compiled code will have
83 	// larger frame sizes. For simplicity, just use global not-target-specific cflags.
84 	// Note: We increase this for both debug and non-debug, as the overflow gap will
85 	//       be compiled into managed code. We always preopt (and build core images) with
86 	//       the debug version. So make the gap consistent (and adjust for the worst).
87 	if len(ctx.Config().SanitizeDevice()) > 0 || len(ctx.Config().SanitizeHost()) > 0 {
88 		cflags = append(cflags,
89 			"-DART_STACK_OVERFLOW_GAP_arm=8192",
90 			"-DART_STACK_OVERFLOW_GAP_arm64=16384",
91 			"-DART_STACK_OVERFLOW_GAP_x86=16384",
92 			"-DART_STACK_OVERFLOW_GAP_x86_64=20480")
93 	} else {
94 		cflags = append(cflags,
95 			"-DART_STACK_OVERFLOW_GAP_arm=8192",
96 			"-DART_STACK_OVERFLOW_GAP_arm64=8192",
97 			"-DART_STACK_OVERFLOW_GAP_x86=8192",
98 			"-DART_STACK_OVERFLOW_GAP_x86_64=8192")
99 	}
100 
101 	if ctx.Config().IsEnvTrue("ART_ENABLE_ADDRESS_SANITIZER") {
102 		// Used to enable full sanitization, i.e., user poisoning, under ASAN.
103 		cflags = append(cflags, "-DART_ENABLE_ADDRESS_SANITIZER=1")
104 		asflags = append(asflags, "-DART_ENABLE_ADDRESS_SANITIZER=1")
105 	}
106 
107 	if !ctx.Config().IsEnvFalse("USE_D8_DESUGAR") {
108 		cflags = append(cflags, "-DUSE_D8_DESUGAR=1")
109 	}
110 
111 	return cflags, asflags
112 }
113 
114 func debugFlags(ctx android.LoadHookContext) []string {
115 	var cflags []string
116 
117 	opt := ctx.Config().GetenvWithDefault("ART_DEBUG_OPT_FLAG", "-O2")
118 	cflags = append(cflags, opt)
119 
120 	return cflags
121 }
122 
123 func deviceFlags(ctx android.LoadHookContext) []string {
124 	var cflags []string
125 	deviceFrameSizeLimit := 1736
126 	if len(ctx.Config().SanitizeDevice()) > 0 {
127 		deviceFrameSizeLimit = 7400
128 	}
129 	cflags = append(cflags,
130 		fmt.Sprintf("-Wframe-larger-than=%d", deviceFrameSizeLimit),
131 		fmt.Sprintf("-DART_FRAME_SIZE_LIMIT=%d", deviceFrameSizeLimit),
132 	)
133 
134 	cflags = append(cflags, "-DART_BASE_ADDRESS="+ctx.Config().LibartImgDeviceBaseAddress())
135 	if ctx.Config().IsEnvTrue("ART_TARGET_LINUX") {
136 		cflags = append(cflags, "-DART_TARGET_LINUX")
137 	} else {
138 		cflags = append(cflags, "-DART_TARGET_ANDROID")
139 	}
140 	minDelta := ctx.Config().GetenvWithDefault("LIBART_IMG_TARGET_MIN_BASE_ADDRESS_DELTA", "-0x1000000")
141 	maxDelta := ctx.Config().GetenvWithDefault("LIBART_IMG_TARGET_MAX_BASE_ADDRESS_DELTA", "0x1000000")
142 	cflags = append(cflags, "-DART_BASE_ADDRESS_MIN_DELTA="+minDelta)
143 	cflags = append(cflags, "-DART_BASE_ADDRESS_MAX_DELTA="+maxDelta)
144 
145 	return cflags
146 }
147 
148 func hostFlags(ctx android.LoadHookContext) []string {
149 	var cflags []string
150 	hostFrameSizeLimit := 1736
151 	if len(ctx.Config().SanitizeHost()) > 0 {
152 		// art/test/137-cfi/cfi.cc
153 		// error: stack frame size of 1944 bytes in function 'Java_Main_unwindInProcess'
154 		hostFrameSizeLimit = 6400
155 	}
156 	cflags = append(cflags,
157 		fmt.Sprintf("-Wframe-larger-than=%d", hostFrameSizeLimit),
158 		fmt.Sprintf("-DART_FRAME_SIZE_LIMIT=%d", hostFrameSizeLimit),
159 	)
160 
161 	cflags = append(cflags, "-DART_BASE_ADDRESS="+ctx.Config().LibartImgHostBaseAddress())
162 	minDelta := ctx.Config().GetenvWithDefault("LIBART_IMG_HOST_MIN_BASE_ADDRESS_DELTA", "-0x1000000")
163 	maxDelta := ctx.Config().GetenvWithDefault("LIBART_IMG_HOST_MAX_BASE_ADDRESS_DELTA", "0x1000000")
164 	cflags = append(cflags, "-DART_BASE_ADDRESS_MIN_DELTA="+minDelta)
165 	cflags = append(cflags, "-DART_BASE_ADDRESS_MAX_DELTA="+maxDelta)
166 
167 	if len(ctx.Config().SanitizeHost()) > 0 && !ctx.Config().IsEnvFalse("ART_ENABLE_ADDRESS_SANITIZER") {
168 		// We enable full sanitization on the host by default.
169 		cflags = append(cflags, "-DART_ENABLE_ADDRESS_SANITIZER=1")
170 	}
171 
172 	return cflags
173 }
174 
175 func globalDefaults(ctx android.LoadHookContext) {
176 	type props struct {
177 		Target struct {
178 			Android struct {
179 				Cflags []string
180 			}
181 			Host struct {
182 				Cflags []string
183 			}
184 		}
185 		Cflags   []string
186 		Asflags  []string
187 		Sanitize struct {
188 			Recover []string
189 		}
190 	}
191 
192 	p := &props{}
193 	p.Cflags, p.Asflags = globalFlags(ctx)
194 	p.Target.Android.Cflags = deviceFlags(ctx)
195 	p.Target.Host.Cflags = hostFlags(ctx)
196 
197 	if ctx.Config().IsEnvTrue("ART_DEX_FILE_ACCESS_TRACKING") {
198 		p.Cflags = append(p.Cflags, "-DART_DEX_FILE_ACCESS_TRACKING")
199 		p.Sanitize.Recover = []string{
200 			"address",
201 		}
202 	}
203 
204 	ctx.AppendProperties(p)
205 }
206 
207 func debugDefaults(ctx android.LoadHookContext) {
208 	type props struct {
209 		Cflags []string
210 	}
211 
212 	p := &props{}
213 	p.Cflags = debugFlags(ctx)
214 	ctx.AppendProperties(p)
215 }
216 
217 func customLinker(ctx android.LoadHookContext) {
218 	linker := ctx.Config().Getenv("CUSTOM_TARGET_LINKER")
219 	type props struct {
220 		DynamicLinker string
221 	}
222 
223 	p := &props{}
224 	if linker != "" {
225 		p.DynamicLinker = linker
226 	}
227 
228 	ctx.AppendProperties(p)
229 }
230 
231 func prefer32Bit(ctx android.LoadHookContext) {
232 	type props struct {
233 		Target struct {
234 			Host struct {
235 				Compile_multilib *string
236 			}
237 		}
238 	}
239 
240 	p := &props{}
241 	if ctx.Config().IsEnvTrue("HOST_PREFER_32_BIT") {
242 		p.Target.Host.Compile_multilib = proptools.StringPtr("prefer32")
243 	}
244 
245 	// Prepend to make it overridable in the blueprints. Note that it doesn't work
246 	// to override the property in a cc_defaults module.
247 	ctx.PrependProperties(p)
248 }
249 
250 var testMapKey = android.NewOnceKey("artTests")
251 
252 func testMap(config android.Config) map[string][]string {
253 	return config.Once(testMapKey, func() interface{} {
254 		return make(map[string][]string)
255 	}).(map[string][]string)
256 }
257 
258 func testInstall(ctx android.InstallHookContext) {
259 	testMap := testMap(ctx.Config())
260 
261 	var name string
262 	if ctx.Host() {
263 		name = "host_"
264 	} else {
265 		name = "device_"
266 	}
267 	name += ctx.Arch().ArchType.String() + "_" + ctx.ModuleName()
268 
269 	artTestMutex.Lock()
270 	defer artTestMutex.Unlock()
271 
272 	tests := testMap[name]
273 	tests = append(tests, ctx.Path().ToMakePath().String())
274 	testMap[name] = tests
275 }
276 
277 var artTestMutex sync.Mutex
278 
279 func init() {
280 	artModuleTypes := []string{
281 		"art_cc_library",
282 		"art_cc_library_static",
283 		"art_cc_binary",
284 		"art_cc_test",
285 		"art_cc_test_library",
286 		"art_cc_defaults",
287 		"libart_cc_defaults",
288 		"libart_static_cc_defaults",
289 		"art_global_defaults",
290 		"art_debug_defaults",
291 		"art_apex_test_host",
292 	}
293 	android.AddNeverAllowRules(
294 		android.NeverAllow().
295 			NotIn("art", "external/vixl").
296 			ModuleType(artModuleTypes...))
297 
298 	android.RegisterModuleType("art_cc_library", artLibrary)
299 	android.RegisterModuleType("art_cc_library_static", artStaticLibrary)
300 	android.RegisterModuleType("art_cc_binary", artBinary)
301 	android.RegisterModuleType("art_cc_test", artTest)
302 	android.RegisterModuleType("art_cc_test_library", artTestLibrary)
303 	android.RegisterModuleType("art_cc_defaults", artDefaultsFactory)
304 	android.RegisterModuleType("libart_cc_defaults", libartDefaultsFactory)
305 	android.RegisterModuleType("libart_static_cc_defaults", libartStaticDefaultsFactory)
306 	android.RegisterModuleType("art_global_defaults", artGlobalDefaultsFactory)
307 	android.RegisterModuleType("art_debug_defaults", artDebugDefaultsFactory)
308 
309 	// ART apex is special because it must include dexpreopt files for bootclasspath jars.
310 	android.RegisterModuleType("art_apex", artApexBundleFactory)
311 	android.RegisterModuleType("art_apex_test", artTestApexBundleFactory)
312 
313 	// TODO: This makes the module disable itself for host if HOST_PREFER_32_BIT is
314 	// set. We need this because the multilib types of binaries listed in the apex
315 	// rule must match the declared type. This is normally not difficult but HOST_PREFER_32_BIT
316 	// changes this to 'prefer32' on all host binaries. Since HOST_PREFER_32_BIT is
317 	// only used for testing we can just disable the module.
318 	// See b/120617876 for more information.
319 	android.RegisterModuleType("art_apex_test_host", artHostTestApexBundleFactory)
320 }
321 
322 func artApexBundleFactory() android.Module {
323 	return apex.ApexBundleFactory(false /*testApex*/, true /*artApex*/)
324 }
325 
326 func artTestApexBundleFactory() android.Module {
327 	return apex.ApexBundleFactory(true /*testApex*/, true /*artApex*/)
328 }
329 
330 func artHostTestApexBundleFactory() android.Module {
331 	module := apex.ApexBundleFactory(true /*testApex*/, true /*artApex*/)
332 	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
333 		if ctx.Config().IsEnvTrue("HOST_PREFER_32_BIT") {
334 			type props struct {
335 				Target struct {
336 					Host struct {
337 						Enabled *bool
338 					}
339 				}
340 			}
341 
342 			p := &props{}
343 			p.Target.Host.Enabled = proptools.BoolPtr(false)
344 			ctx.AppendProperties(p)
345 			log.Print("Disabling host build of " + ctx.ModuleName() + " for HOST_PREFER_32_BIT=true")
346 		}
347 	})
348 
349 	return module
350 }
351 
352 func artGlobalDefaultsFactory() android.Module {
353 	module := artDefaultsFactory()
354 	android.AddLoadHook(module, globalDefaults)
355 
356 	return module
357 }
358 
359 func artDebugDefaultsFactory() android.Module {
360 	module := artDefaultsFactory()
361 	android.AddLoadHook(module, debugDefaults)
362 
363 	return module
364 }
365 
366 func artDefaultsFactory() android.Module {
367 	c := &codegenProperties{}
368 	module := cc.DefaultsFactory(c)
369 	android.AddLoadHook(module, func(ctx android.LoadHookContext) { codegen(ctx, c, staticAndSharedLibrary) })
370 
371 	return module
372 }
373 
374 func libartDefaultsFactory() android.Module {
375 	c := &codegenProperties{}
376 	module := cc.DefaultsFactory(c)
377 	android.AddLoadHook(module, func(ctx android.LoadHookContext) { codegen(ctx, c, staticAndSharedLibrary) })
378 
379 	return module
380 }
381 
382 func libartStaticDefaultsFactory() android.Module {
383 	c := &codegenProperties{}
384 	module := cc.DefaultsFactory(c)
385 	android.AddLoadHook(module, func(ctx android.LoadHookContext) { codegen(ctx, c, staticLibrary) })
386 
387 	return module
388 }
389 
390 func artLibrary() android.Module {
391 	module := cc.LibraryFactory()
392 
393 	installCodegenCustomizer(module, staticAndSharedLibrary)
394 
395 	return module
396 }
397 
398 func artStaticLibrary() android.Module {
399 	module := cc.LibraryStaticFactory()
400 
401 	installCodegenCustomizer(module, staticLibrary)
402 
403 	return module
404 }
405 
406 func artBinary() android.Module {
407 	module := cc.BinaryFactory()
408 
409 	android.AddLoadHook(module, customLinker)
410 	android.AddLoadHook(module, prefer32Bit)
411 	return module
412 }
413 
414 func artTest() android.Module {
415 	module := cc.TestFactory()
416 
417 	installCodegenCustomizer(module, binary)
418 
419 	android.AddLoadHook(module, customLinker)
420 	android.AddLoadHook(module, prefer32Bit)
421 	android.AddInstallHook(module, testInstall)
422 	return module
423 }
424 
425 func artTestLibrary() android.Module {
426 	module := cc.TestLibraryFactory()
427 
428 	installCodegenCustomizer(module, staticAndSharedLibrary)
429 
430 	android.AddLoadHook(module, prefer32Bit)
431 	android.AddInstallHook(module, testInstall)
432 	return module
433 }
434