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