diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go index 7dc990b71..5d8c351ab 100644 --- a/cc/config/toolchain.go +++ b/cc/config/toolchain.go @@ -209,58 +209,58 @@ func addPrefix(list []string, prefix string) []string { return list } -func LibclangRuntimeLibrary(t Toolchain, library string) string { +func LibclangRuntimeLibrary(library string) string { return "libclang_rt." + library } -func BuiltinsRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "builtins") +func BuiltinsRuntimeLibrary() string { + return LibclangRuntimeLibrary("builtins") } -func AddressSanitizerRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "asan") +func AddressSanitizerRuntimeLibrary() string { + return LibclangRuntimeLibrary("asan") } -func AddressSanitizerStaticRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "asan.static") +func AddressSanitizerStaticRuntimeLibrary() string { + return LibclangRuntimeLibrary("asan.static") } -func AddressSanitizerCXXStaticRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "asan_cxx.static") +func AddressSanitizerCXXStaticRuntimeLibrary() string { + return LibclangRuntimeLibrary("asan_cxx.static") } -func HWAddressSanitizerRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "hwasan") +func HWAddressSanitizerRuntimeLibrary() string { + return LibclangRuntimeLibrary("hwasan") } -func HWAddressSanitizerStaticLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "hwasan_static") +func HWAddressSanitizerStaticLibrary() string { + return LibclangRuntimeLibrary("hwasan_static") } -func UndefinedBehaviorSanitizerRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "ubsan_standalone") +func UndefinedBehaviorSanitizerRuntimeLibrary() string { + return LibclangRuntimeLibrary("ubsan_standalone") } -func UndefinedBehaviorSanitizerMinimalRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "ubsan_minimal") +func UndefinedBehaviorSanitizerMinimalRuntimeLibrary() string { + return LibclangRuntimeLibrary("ubsan_minimal") } -func ThreadSanitizerRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "tsan") +func ThreadSanitizerRuntimeLibrary() string { + return LibclangRuntimeLibrary("tsan") } -func ScudoRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "scudo") +func ScudoRuntimeLibrary() string { + return LibclangRuntimeLibrary("scudo") } -func ScudoMinimalRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "scudo_minimal") +func ScudoMinimalRuntimeLibrary() string { + return LibclangRuntimeLibrary("scudo_minimal") } -func LibFuzzerRuntimeLibrary(t Toolchain) string { - return LibclangRuntimeLibrary(t, "fuzzer") +func LibFuzzerRuntimeLibrary() string { + return LibclangRuntimeLibrary("fuzzer") } -func LibFuzzerRuntimeInterceptors(t Toolchain) string { - return LibclangRuntimeLibrary(t, "fuzzer_interceptors") +func LibFuzzerRuntimeInterceptors() string { + return LibclangRuntimeLibrary("fuzzer_interceptors") } diff --git a/cc/fuzz.go b/cc/fuzz.go index 164ec997b..92f2c5e44 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -128,13 +128,13 @@ func (fuzzBin *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps { if ctx.Config().Getenv("FUZZ_FRAMEWORK") == "AFL" { deps.HeaderLibs = append(deps.HeaderLibs, "libafl_headers") } else { - deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary(ctx.toolchain())) + deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary()) // Fuzzers built with HWASAN should use the interceptors for better // mutation based on signals in strcmp, memcpy, etc. This is only needed for // fuzz targets, not generic HWASAN-ified binaries or libraries. if module, ok := ctx.Module().(*Module); ok { if module.IsSanitizerEnabled(Hwasan) { - deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeInterceptors(ctx.toolchain())) + deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeInterceptors()) } } } diff --git a/cc/linker.go b/cc/linker.go index f325c125d..1b5a33a9f 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -431,7 +431,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { if ctx.toolchain().Bionic() { // libclang_rt.builtins has to be last on the command line if linker.Properties.libCrt() && !ctx.header() { - deps.UnexportedStaticLibs = append(deps.UnexportedStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain())) + deps.UnexportedStaticLibs = append(deps.UnexportedStaticLibs, config.BuiltinsRuntimeLibrary()) } if inList("libdl", deps.SharedLibs) { @@ -454,7 +454,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { } } else if ctx.toolchain().Musl() { if linker.Properties.libCrt() && !ctx.header() { - deps.UnexportedStaticLibs = append(deps.UnexportedStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain())) + deps.UnexportedStaticLibs = append(deps.UnexportedStaticLibs, config.BuiltinsRuntimeLibrary()) } } diff --git a/cc/makevars.go b/cc/makevars.go index 51bcbf090..9d29affcd 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -28,6 +28,16 @@ var ( modulesWarningsAllowedKey = android.NewOnceKey("ModulesWarningsAllowed") modulesUsingWnoErrorKey = android.NewOnceKey("ModulesUsingWnoError") modulesMissingProfileFileKey = android.NewOnceKey("ModulesMissingProfileFile") + sanitizerVariables = map[string]string{ + "ADDRESS_SANITIZER_RUNTIME_LIBRARY": config.AddressSanitizerRuntimeLibrary(), + "HWADDRESS_SANITIZER_RUNTIME_LIBRARY": config.HWAddressSanitizerRuntimeLibrary(), + "HWADDRESS_SANITIZER_STATIC_LIBRARY": config.HWAddressSanitizerStaticLibrary(), + "UBSAN_RUNTIME_LIBRARY": config.UndefinedBehaviorSanitizerRuntimeLibrary(), + "UBSAN_MINIMAL_RUNTIME_LIBRARY": config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(), + "TSAN_RUNTIME_LIBRARY": config.ThreadSanitizerRuntimeLibrary(), + "SCUDO_RUNTIME_LIBRARY": config.ScudoRuntimeLibrary(), + "SCUDO_MINIMAL_RUNTIME_LIBRARY": config.ScudoMinimalRuntimeLibrary(), + } ) func init() { @@ -261,43 +271,9 @@ func makeVarsToolchain(ctx android.MakeVarsContext, secondPrefix string, }, " ")) if target.Os.Class == android.Device { - sanitizerVariables := map[string]string{ - "ADDRESS_SANITIZER_RUNTIME_LIBRARY": config.AddressSanitizerRuntimeLibrary(toolchain), - "HWADDRESS_SANITIZER_RUNTIME_LIBRARY": config.HWAddressSanitizerRuntimeLibrary(toolchain), - "HWADDRESS_SANITIZER_STATIC_LIBRARY": config.HWAddressSanitizerStaticLibrary(toolchain), - "UBSAN_RUNTIME_LIBRARY": config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain), - "UBSAN_MINIMAL_RUNTIME_LIBRARY": config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain), - "TSAN_RUNTIME_LIBRARY": config.ThreadSanitizerRuntimeLibrary(toolchain), - "SCUDO_RUNTIME_LIBRARY": config.ScudoRuntimeLibrary(toolchain), - "SCUDO_MINIMAL_RUNTIME_LIBRARY": config.ScudoMinimalRuntimeLibrary(toolchain), - } - for variable, value := range sanitizerVariables { ctx.Strict(secondPrefix+variable, value) } - - sanitizerLibs := android.SortedStringValues(sanitizerVariables) - var sanitizerLibStems []string - ctx.VisitAllModules(func(m android.Module) { - if !m.Enabled(ctx) { - return - } - - ccModule, _ := m.(*Module) - if ccModule == nil || ccModule.library == nil || !ccModule.library.shared() { - return - } - - if android.InList(strings.TrimPrefix(ctx.ModuleName(m), "prebuilt_"), sanitizerLibs) && - m.Target().Os == target.Os && m.Target().Arch.ArchType == target.Arch.ArchType { - outputFile := ccModule.outputFile - if outputFile.Valid() { - sanitizerLibStems = append(sanitizerLibStems, outputFile.Path().Base()) - } - } - }) - sanitizerLibStems = android.SortedUniqueStrings(sanitizerLibStems) - ctx.Strict(secondPrefix+"SANITIZER_STEMS", strings.Join(sanitizerLibStems, " ")) } // This is used by external/gentoo/... diff --git a/cc/sanitize.go b/cc/sanitize.go index 1a94729c6..e6075ada4 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -25,6 +25,7 @@ import ( "android/soong/android" "android/soong/cc/config" + "android/soong/etc" ) var ( @@ -408,6 +409,8 @@ func init() { android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider) android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider) android.RegisterMakeVarsProvider(pctx, memtagStackMakeVarsProvider) + + RegisterSanitizerLibrariesTxtType(android.InitRegistrationContext) } func (sanitize *sanitize) props() []interface{} { @@ -1316,7 +1319,7 @@ func (s *sanitizerSplitMutator) Mutate(mctx android.BottomUpMutatorContext, vari } else if s.sanitizer == cfi { cfiStaticLibs(mctx.Config()).add(c, c.Module().Name()) } else if s.sanitizer == Memtag_stack { - memtagStackStaticLibs(mctx.Config()).add(c, c.Module().Name()); + memtagStackStaticLibs(mctx.Config()).add(c, c.Module().Name()) } } } else if c.IsSanitizerEnabled(s.sanitizer) { @@ -1522,25 +1525,25 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { if Bool(sanProps.Address) { if toolchain.Musl() || (c.staticBinary() && toolchain.Bionic()) { // Use a static runtime for musl to match what clang does for glibc. - addStaticDeps(config.AddressSanitizerStaticRuntimeLibrary(toolchain), false) - addStaticDeps(config.AddressSanitizerCXXStaticRuntimeLibrary(toolchain), false) + addStaticDeps(config.AddressSanitizerStaticRuntimeLibrary(), false) + addStaticDeps(config.AddressSanitizerCXXStaticRuntimeLibrary(), false) } else { - runtimeSharedLibrary = config.AddressSanitizerRuntimeLibrary(toolchain) + runtimeSharedLibrary = config.AddressSanitizerRuntimeLibrary() } } else if Bool(sanProps.Hwaddress) { if c.staticBinary() { - addStaticDeps(config.HWAddressSanitizerStaticLibrary(toolchain), true) + addStaticDeps(config.HWAddressSanitizerStaticLibrary(), true) addStaticDeps("libdl", false) } else { - runtimeSharedLibrary = config.HWAddressSanitizerRuntimeLibrary(toolchain) + runtimeSharedLibrary = config.HWAddressSanitizerRuntimeLibrary() } } else if Bool(sanProps.Thread) { - runtimeSharedLibrary = config.ThreadSanitizerRuntimeLibrary(toolchain) + runtimeSharedLibrary = config.ThreadSanitizerRuntimeLibrary() } else if Bool(sanProps.Scudo) { if len(diagSanitizers) == 0 && !c.sanitize.Properties.UbsanRuntimeDep { - runtimeSharedLibrary = config.ScudoMinimalRuntimeLibrary(toolchain) + runtimeSharedLibrary = config.ScudoMinimalRuntimeLibrary() } else { - runtimeSharedLibrary = config.ScudoRuntimeLibrary(toolchain) + runtimeSharedLibrary = config.ScudoRuntimeLibrary() } } else if len(diagSanitizers) > 0 || c.sanitize.Properties.UbsanRuntimeDep || Bool(sanProps.Fuzzer) || @@ -1553,17 +1556,17 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { // Also manually add a static runtime for musl to match what clang does for glibc. // Otherwise dlopening libraries that depend on libclang_rt.ubsan_standalone.so fails with: // Error relocating ...: initial-exec TLS resolves to dynamic definition - addStaticDeps(config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain)+".static", true) + addStaticDeps(config.UndefinedBehaviorSanitizerRuntimeLibrary()+".static", true) } else { - runtimeSharedLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain) + runtimeSharedLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary() } } if enableMinimalRuntime(c.sanitize) || c.sanitize.Properties.MinimalRuntimeDep { - addStaticDeps(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain), true) + addStaticDeps(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(), true) } if c.sanitize.Properties.BuiltinsDep { - addStaticDeps(config.BuiltinsRuntimeLibrary(toolchain), true) + addStaticDeps(config.BuiltinsRuntimeLibrary(), true) } if runtimeSharedLibrary != "" && (toolchain.Bionic() || toolchain.Musl()) { @@ -1787,3 +1790,126 @@ func hwasanMakeVarsProvider(ctx android.MakeVarsContext) { func memtagStackMakeVarsProvider(ctx android.MakeVarsContext) { memtagStackStaticLibs(ctx.Config()).exportToMake(ctx) } + +type sanitizerLibrariesTxtModule struct { + android.ModuleBase + + outputFile android.OutputPath +} + +var _ etc.PrebuiltEtcModule = (*sanitizerLibrariesTxtModule)(nil) +var _ android.OutputFileProducer = (*sanitizerLibrariesTxtModule)(nil) + +func RegisterSanitizerLibrariesTxtType(ctx android.RegistrationContext) { + ctx.RegisterModuleType("sanitizer_libraries_txt", sanitizerLibrariesTxtFactory) +} + +func sanitizerLibrariesTxtFactory() android.Module { + m := &sanitizerLibrariesTxtModule{} + android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) + return m +} + +type sanitizerLibraryDependencyTag struct { + blueprint.BaseDependencyTag +} + +func (t sanitizerLibraryDependencyTag) AllowDisabledModuleDependency(target android.Module) bool { + return true +} + +var _ android.AllowDisabledModuleDependency = (*sanitizerLibraryDependencyTag)(nil) + +func (txt *sanitizerLibrariesTxtModule) DepsMutator(actx android.BottomUpMutatorContext) { + targets := actx.Config().Targets[android.Android] + depTag := sanitizerLibraryDependencyTag{} + + for _, target := range targets { + variation := append(target.Variations(), + blueprint.Variation{Mutator: "image", Variation: ""}, + blueprint.Variation{Mutator: "sdk", Variation: ""}, + blueprint.Variation{Mutator: "link", Variation: "shared"}, + ) + for _, lib := range android.SortedStringValues(sanitizerVariables) { + if actx.OtherModuleFarDependencyVariantExists(variation, lib) { + actx.AddFarVariationDependencies(variation, depTag, lib) + } + + prebuiltLibName := "prebuilt_" + lib + if actx.OtherModuleFarDependencyVariantExists(variation, prebuiltLibName) { + actx.AddFarVariationDependencies(variation, depTag, prebuiltLibName) + } + } + } + +} + +func (txt *sanitizerLibrariesTxtModule) getSanitizerLibs(ctx android.ModuleContext) string { + var sanitizerLibStems []string + + ctx.VisitDirectDepsIf(func(m android.Module) bool { + if !m.Enabled(ctx) { + return false + } + + ccModule, _ := m.(*Module) + if ccModule == nil || ccModule.library == nil || !ccModule.library.shared() { + return false + } + + targets := ctx.Config().Targets[android.Android] + + for _, target := range targets { + if m.Target().Os == target.Os && m.Target().Arch.ArchType == target.Arch.ArchType { + return true + } + } + + return false + }, func(m android.Module) { + ccModule, _ := m.(*Module) + outputFile := ccModule.outputFile + if outputFile.Valid() { + sanitizerLibStems = append(sanitizerLibStems, outputFile.Path().Base()) + } + }) + + sanitizerLibStems = android.SortedUniqueStrings(sanitizerLibStems) + return strings.Join(sanitizerLibStems, "\n") +} + +func (txt *sanitizerLibrariesTxtModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + filename := txt.Name() + + txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath + android.WriteFileRule(ctx, txt.outputFile, txt.getSanitizerLibs(ctx)) + + installPath := android.PathForModuleInstall(ctx, "etc") + ctx.InstallFile(installPath, filename, txt.outputFile) +} + +func (txt *sanitizerLibrariesTxtModule) AndroidMkEntries() []android.AndroidMkEntries { + return []android.AndroidMkEntries{{ + Class: "ETC", + OutputFile: android.OptionalPathForPath(txt.outputFile), + }} +} + +// PrebuiltEtcModule interface +func (txt *sanitizerLibrariesTxtModule) OutputFile() android.OutputPath { + return txt.outputFile +} + +// PrebuiltEtcModule interface +func (txt *sanitizerLibrariesTxtModule) BaseDir() string { + return "etc" +} + +// PrebuiltEtcModule interface +func (txt *sanitizerLibrariesTxtModule) SubDir() string { + return "" +} + +func (txt *sanitizerLibrariesTxtModule) OutputFiles(tag string) (android.Paths, error) { + return android.Paths{txt.outputFile}, nil +}