Home | History | Annotate | Download | only in build
      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