Home | History | Annotate | Download | only in soong
      1 //
      2 // Copyright (C) 2017 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 package clangprebuilts
     18 
     19 import (
     20 	"path"
     21 	"path/filepath"
     22 	"strings"
     23 
     24 	"github.com/google/blueprint/proptools"
     25 
     26 	"android/soong/android"
     27 	"android/soong/cc"
     28 	"android/soong/cc/config"
     29 )
     30 
     31 // This module is used to generate libfuzzer static libraries and libclang_rt.* shared libraries. When
     32 // LLVM_PREBUILTS_VERSION and LLVM_RELEASE_VERSION are set, the library will
     33 // generated from the given path.
     34 
     35 func init() {
     36 	android.RegisterModuleType("libfuzzer_prebuilt_library_static",
     37 		libfuzzerPrebuiltLibraryStaticFactory)
     38 	android.RegisterModuleType("libclang_rt_prebuilt_library_shared",
     39 		libClangRtPrebuiltLibrarySharedFactory)
     40 }
     41 
     42 func getClangDirs(ctx android.LoadHookContext) (libDir string, headerDir string) {
     43 	clangDir := path.Join(
     44 		"./",
     45 		ctx.AConfig().GetenvWithDefault("LLVM_PREBUILTS_VERSION", config.ClangDefaultVersion),
     46 	)
     47 	headerDir = path.Join(clangDir, "prebuilt_include", "llvm", "lib", "Fuzzer")
     48 	releaseVersion := ctx.AConfig().GetenvWithDefault("LLVM_RELEASE_VERSION",
     49 		config.ClangDefaultShortVersion)
     50 	libDir = path.Join(clangDir, "lib64", "clang", releaseVersion, "lib", "linux")
     51 	return
     52 }
     53 
     54 type archProps struct {
     55 	Android_arm struct {
     56 		Srcs []string
     57 	}
     58 	Android_arm64 struct {
     59 		Srcs []string
     60 	}
     61 	Android_mips struct {
     62 		Srcs []string
     63 	}
     64 	Android_mips64 struct {
     65 		Srcs []string
     66 	}
     67 	Android_x86 struct {
     68 		Srcs []string
     69 	}
     70 	Android_x86_64 struct {
     71 		Srcs []string
     72 	}
     73 }
     74 
     75 func libfuzzerPrebuiltLibraryStatic(ctx android.LoadHookContext) {
     76 	// Because of b/38393317, changing clang base dir is not allowed.  Mark
     77 	// libFuzzer as disabled if LLVM_PREBUILTS_BASE is used to specify a
     78 	// different base dir other than $ANDROID_BUILD_TOP/prebuilts/clang/host
     79 	// (i.e. $CWD/..).  libFuzzer would be unavailable only for the stage2
     80 	// of the aosp-llvm build, where it is not needed.
     81 	var enableLibFuzzer bool
     82 	enableLibFuzzer = true
     83 	if prebuiltsBase := ctx.AConfig().Getenv("LLVM_PREBUILTS_BASE"); prebuiltsBase != "" {
     84 		prebuiltsBaseAbs, err1 := filepath.Abs(prebuiltsBase)
     85 		moduleBaseAbs, err2 := filepath.Abs("..")
     86 		if err1 == nil && err2 == nil && prebuiltsBaseAbs != moduleBaseAbs {
     87 			enableLibFuzzer = false
     88 		}
     89 	}
     90 
     91 	libDir, headerDir := getClangDirs(ctx)
     92 
     93 	type props struct {
     94 		Enabled             *bool
     95 		Export_include_dirs []string
     96 		Target              archProps
     97 	}
     98 
     99 	p := &props{}
    100 
    101 	p.Enabled = proptools.BoolPtr(enableLibFuzzer)
    102 	p.Export_include_dirs = []string{headerDir}
    103 	p.Target.Android_arm.Srcs = []string{path.Join(libDir, "arm/libFuzzer.a")}
    104 	p.Target.Android_arm64.Srcs = []string{path.Join(libDir, "aarch64/libFuzzer.a")}
    105 	p.Target.Android_mips.Srcs = []string{path.Join(libDir, "mips/libFuzzer.a")}
    106 	p.Target.Android_mips64.Srcs = []string{path.Join(libDir, "mips64/libFuzzer.a")}
    107 	p.Target.Android_x86.Srcs = []string{path.Join(libDir, "i386/libFuzzer.a")}
    108 	p.Target.Android_x86_64.Srcs = []string{path.Join(libDir, "x86_64/libFuzzer.a")}
    109 	ctx.AppendProperties(p)
    110 }
    111 
    112 func libClangRtPrebuiltLibraryShared(ctx android.LoadHookContext) {
    113 	if ctx.AConfig().IsEnvTrue("FORCE_BUILD_SANITIZER_SHARED_OBJECTS") {
    114 		return
    115 	}
    116 
    117 	libDir, _ := getClangDirs(ctx)
    118 
    119 	type props struct {
    120 		Srcs []string
    121 		System_shared_libs []string
    122 		Sanitize struct {
    123 			Never bool
    124 		}
    125 		Strip struct {
    126 			None bool
    127 		}
    128 		Pack_relocations *bool
    129 		Stl *string
    130 	}
    131 
    132 	p := &props{}
    133 
    134 	name := strings.Replace(ctx.ModuleName(), "prebuilt_", "", 1)
    135 
    136 	p.Srcs = []string{path.Join(libDir, name+".so")}
    137 	p.System_shared_libs = []string{}
    138 	p.Sanitize.Never = true
    139 	p.Strip.None = true
    140 	disable := false
    141 	p.Pack_relocations = &disable
    142 	none := "none"
    143 	p.Stl = &none
    144 	ctx.AppendProperties(p)
    145 }
    146 
    147 func libfuzzerPrebuiltLibraryStaticFactory() android.Module {
    148 	module, _ := cc.NewPrebuiltStaticLibrary(android.HostAndDeviceSupported)
    149 	android.AddLoadHook(module, libfuzzerPrebuiltLibraryStatic)
    150 	return module.Init()
    151 }
    152 
    153 func libClangRtPrebuiltLibrarySharedFactory() android.Module {
    154 	module, _ := cc.NewPrebuiltSharedLibrary(android.DeviceSupported)
    155 	android.AddLoadHook(module, libClangRtPrebuiltLibraryShared)
    156 	return module.Init()
    157 }
    158