diff --git a/cc/fuzz.go b/cc/fuzz.go index f5642d67d..8dedb2386 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -144,20 +144,25 @@ func (fuzzBin *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps { } func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { + subdir := "lib" + if ctx.inVendor() { + subdir = "lib/vendor" + } + flags = fuzz.binaryDecorator.linkerFlags(ctx, flags) // RunPaths on devices isn't instantiated by the base linker. `../lib` for // installed fuzz targets (both host and device), and `./lib` for fuzz // target packages. - flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/lib`) + flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/`+subdir) // When running on device, fuzz targets with vendor: true set will be in // fuzzer_name/vendor/fuzzer_name (note the extra 'vendor' and thus need to // link with libraries in ../../lib/. Non-vendor binaries only need to look // one level up, in ../lib/. if ctx.inVendor() { - flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../../lib`) + flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../../`+subdir) } else { - flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../lib`) + flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../`+subdir) } return flags @@ -216,19 +221,27 @@ func IsValidSharedDependency(dependency android.Module) bool { } func SharedLibraryInstallLocation( - libraryBase string, isHost bool, fuzzDir string, archString string) string { + libraryBase string, isHost bool, isVendor bool, fuzzDir string, archString string) string { installLocation := "$(PRODUCT_OUT)/data" if isHost { installLocation = "$(HOST_OUT)" } + subdir := "lib" + if isVendor { + subdir = "lib/vendor" + } installLocation = filepath.Join( - installLocation, fuzzDir, archString, "lib", libraryBase) + installLocation, fuzzDir, archString, subdir, libraryBase) return installLocation } // Get the device-only shared library symbols install directory. -func SharedLibrarySymbolsInstallLocation(libraryBase string, fuzzDir string, archString string) string { - return filepath.Join("$(PRODUCT_OUT)/symbols/data/", fuzzDir, archString, "/lib/", libraryBase) +func SharedLibrarySymbolsInstallLocation(libraryBase string, isVendor bool, fuzzDir string, archString string) string { + subdir := "lib" + if isVendor { + subdir = "lib/vendor" + } + return filepath.Join("$(PRODUCT_OUT)/symbols/data/", fuzzDir, archString, subdir, libraryBase) } func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) { @@ -239,16 +252,29 @@ func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) { // Grab the list of required shared libraries. fuzzBin.sharedLibraries, _ = CollectAllSharedDependencies(ctx) + // TODO: does not mirror Android linkernamespaces + // the logic here has special cases for vendor, but it would need more work to + // work in arbitrary partitions, so just surface errors early for a few cases + // + // Even without these, there are certain situations across linkernamespaces + // that this won't support. For instance, you might have: + // + // my_fuzzer (vendor) -> libbinder_ndk (core) -> libbinder (vendor) + // + // This dependency chain wouldn't be possible to express in the current + // logic because all the deps currently match the variant of the source + // module. + for _, ruleBuilderInstall := range fuzzBin.sharedLibraries { install := ruleBuilderInstall.To fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps, SharedLibraryInstallLocation( - install, ctx.Host(), installBase, ctx.Arch().ArchType.String())) + install, ctx.Host(), ctx.inVendor(), installBase, ctx.Arch().ArchType.String())) // Also add the dependency on the shared library symbols dir. if !ctx.Host() { fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps, - SharedLibrarySymbolsInstallLocation(install, installBase, ctx.Arch().ArchType.String())) + SharedLibrarySymbolsInstallLocation(install, ctx.inVendor(), installBase, ctx.Arch().ArchType.String())) } } @@ -407,6 +433,10 @@ func (s *ccRustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) } sharedLibsInstallDirPrefix := "lib" + if ccModule.InVendor() { + sharedLibsInstallDirPrefix = "lib/vendor" + } + if !ccModule.IsFuzzModule() { return } @@ -499,7 +529,7 @@ func GetSharedLibsToZip(sharedLibraries android.RuleBuilderInstalls, module Link // install it to the output directory. Setup the install destination here, // which will be used by $(copy-many-files) in the Make backend. installDestination := SharedLibraryInstallLocation( - install, module.Host(), fuzzDir, archString) + install, module.Host(), module.InVendor(), fuzzDir, archString) if (*sharedLibraryInstalled)[installDestination] { continue } @@ -517,7 +547,7 @@ func GetSharedLibsToZip(sharedLibraries android.RuleBuilderInstalls, module Link // we want symbolization tools (like `stack`) to be able to find the symbols // in $ANDROID_PRODUCT_OUT/symbols automagically. if !module.Host() { - symbolsInstallDestination := SharedLibrarySymbolsInstallLocation(install, fuzzDir, archString) + symbolsInstallDestination := SharedLibrarySymbolsInstallLocation(install, module.InVendor(), fuzzDir, archString) symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$") s.SharedLibInstallStrings = append(s.SharedLibInstallStrings, library.String()+":"+symbolsInstallDestination) diff --git a/rust/fuzz.go b/rust/fuzz.go index bacfa2d1b..1770d2e65 100644 --- a/rust/fuzz.go +++ b/rust/fuzz.go @@ -142,12 +142,12 @@ func (fuzz *fuzzDecorator) install(ctx ModuleContext) { fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, cc.SharedLibraryInstallLocation( - install, ctx.Host(), installBase, ctx.Arch().ArchType.String())) + install, ctx.Host(), ctx.InstallInVendor(), installBase, ctx.Arch().ArchType.String())) // Also add the dependency on the shared library symbols dir. if !ctx.Host() { fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, - cc.SharedLibrarySymbolsInstallLocation(install, installBase, ctx.Arch().ArchType.String())) + cc.SharedLibrarySymbolsInstallLocation(install, ctx.InstallInVendor(), installBase, ctx.Arch().ArchType.String())) } }