Merge "Move sanitizer.libraries.txt logic into Soong" into main

This commit is contained in:
Kiyoung Kim
2024-05-24 00:39:00 +00:00
committed by Gerrit Code Review
5 changed files with 180 additions and 78 deletions

View File

@@ -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")
}

View File

@@ -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())
}
}
}

View File

@@ -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())
}
}

View File

@@ -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/...

View File

@@ -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
}