Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5dc62c94 authored by Colin Cross's avatar Colin Cross
Browse files

Add sanitizer tests for musl

Add tests that verify sanitizer behaviors for musl.

Test: sanitize_test.go
Change-Id: I1f0a51cc103ac14d1738cb223e216ee0e32d8550
parent 9e87f0a6
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -401,7 +401,7 @@ func TestArchMutator(t *testing.T) {
		{
			name: "same arch host and host cross",
			preparer: FixtureModifyConfig(func(config Config) {
				modifyTestConfigForMusl(config)
				ModifyTestConfigForMusl(config)
				modifyTestConfigForMuslArm64HostCross(config)
			}),
			fooVariants:         []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"},
@@ -705,7 +705,7 @@ func TestArchProperties(t *testing.T) {
		{
			name:     "linux_musl",
			goOS:     "linux",
			preparer: FixtureModifyConfig(modifyTestConfigForMusl),
			preparer: FixtureModifyConfig(ModifyTestConfigForMusl),
			results: []result{
				{
					module:   "foo",
+7 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ package android

import (
	"fmt"
	"runtime"
	"strings"
	"testing"
)
@@ -379,6 +380,12 @@ func FixtureModifyProductVariables(mutator func(variables FixtureProductVariable
	})
}

var PrepareForSkipTestOnMac = newSimpleFixturePreparer(func(fixture *fixture) {
	if runtime.GOOS != "linux" {
		fixture.t.Skip("Test is only supported on linux.")
	}
})

// PrepareForDebug_DO_NOT_SUBMIT puts the fixture into debug which will cause it to output its
// state before running the test.
//
+2 −1
Original line number Diff line number Diff line
@@ -109,7 +109,8 @@ func modifyTestConfigToSupportArchMutator(testConfig Config) {
	config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon")
}

func modifyTestConfigForMusl(config Config) {
// ModifyTestConfigForMusl takes a Config returned by TestConfig and changes the host targets from glibc to musl.
func ModifyTestConfigForMusl(config Config) {
	delete(config.Targets, config.BuildOS)
	config.productVariables.HostMusl = boolPtr(true)
	determineBuildOS(config.config)
+101 −20
Original line number Diff line number Diff line
@@ -28,12 +28,22 @@ import (
var prepareForAsanTest = android.FixtureAddFile("asan/Android.bp", []byte(`
	cc_library_shared {
		name: "libclang_rt.asan",
		host_supported: true,
	}
	cc_library_static {
		name: "libclang_rt.asan.static",
		host_supported: true,
	}
	cc_library_static {
		name: "libclang_rt.asan_cxx.static",
		host_supported: true,
	}
`))

var prepareForTsanTest = android.FixtureAddFile("tsan/Android.bp", []byte(`
	cc_library_shared {
		name: "libclang_rt.tsan",
		host_supported: true,
	}
`))

@@ -54,6 +64,19 @@ func expectSharedLinkDep(t *testing.T, ctx providerInterface, from, to android.T
	}
}

// expectNoSharedLinkDep verifies that the from module links against the to module as a
// shared library.
func expectNoSharedLinkDep(t *testing.T, ctx providerInterface, from, to android.TestingModule) {
	t.Helper()
	fromLink := from.Description("link")
	toInfo := ctx.ModuleProvider(to.Module(), SharedLibraryInfoProvider).(SharedLibraryInfo)

	if g, w := fromLink.OrderOnly.Strings(), toInfo.SharedLibrary.RelativeToTop().String(); android.InList(w, g) {
		t.Errorf("%s should not link against %s, expected %q, got %q",
			from.Module(), to.Module(), w, g)
	}
}

// expectStaticLinkDep verifies that the from module links against the to module as a
// static library.
func expectStaticLinkDep(t *testing.T, ctx providerInterface, from, to android.TestingModule) {
@@ -68,6 +91,20 @@ func expectStaticLinkDep(t *testing.T, ctx providerInterface, from, to android.T

}

// expectNoStaticLinkDep verifies that the from module links against the to module as a
// static library.
func expectNoStaticLinkDep(t *testing.T, ctx providerInterface, from, to android.TestingModule) {
	t.Helper()
	fromLink := from.Description("link")
	toInfo := ctx.ModuleProvider(to.Module(), StaticLibraryInfoProvider).(StaticLibraryInfo)

	if g, w := fromLink.Implicits.Strings(), toInfo.StaticLibrary.RelativeToTop().String(); android.InList(w, g) {
		t.Errorf("%s should not link against %s, expected %q, got %q",
			from.Module(), to.Module(), w, g)
	}

}

// expectInstallDep verifies that the install rule of the from module depends on the
// install rule of the to module.
func expectInstallDep(t *testing.T, from, to android.TestingModule) {
@@ -85,6 +122,13 @@ func expectInstallDep(t *testing.T, from, to android.TestingModule) {
	}
}

type expectedRuntimeLinkage int

const (
	RUNTIME_LINKAGE_NONE   = expectedRuntimeLinkage(0)
	RUNTIME_LINKAGE_SHARED = iota
)

func TestAsan(t *testing.T) {
	t.Parallel()
	bp := `
@@ -162,12 +206,14 @@ func TestAsan(t *testing.T) {

	`

	result := android.GroupFixturePreparers(
	preparer := android.GroupFixturePreparers(
		prepareForCcTest,
		prepareForAsanTest,
	).RunTestWithBp(t, bp)
	)
	buildOS := preparer.RunTestWithBp(t, bp).Config.BuildOSTarget.String()

	check := func(t *testing.T, result *android.TestResult, variant string) {
	check := func(t *testing.T, variant string, runtimeLinkage expectedRuntimeLinkage, preparer android.FixturePreparer) {
		result := preparer.RunTestWithBp(t, bp)
		ctx := result.TestContext
		asanVariant := variant + "_asan"
		sharedVariant := variant + "_shared"
@@ -198,6 +244,8 @@ func TestAsan(t *testing.T) {
		libStaticAsan := result.ModuleForTests("libstatic_asan", staticAsanVariant)
		libStaticAsanNoAsanVariant := result.ModuleForTests("libstatic_asan", staticVariant)

		libAsanSharedRuntime := result.ModuleForTests("libclang_rt.asan", sharedVariant)

		expectSharedLinkDep(t, ctx, binWithAsan, libShared)
		expectSharedLinkDep(t, ctx, binWithAsan, libAsan)
		expectSharedLinkDep(t, ctx, libShared, libTransitive)
@@ -227,10 +275,28 @@ func TestAsan(t *testing.T) {
		expectInstallDep(t, binNoAsan, libTransitive)
		expectInstallDep(t, libShared, libTransitive)
		expectInstallDep(t, libAsan, libTransitive)
	}

	t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) })
	t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") })
		if runtimeLinkage == RUNTIME_LINKAGE_SHARED {
			expectSharedLinkDep(t, ctx, binWithAsan, libAsanSharedRuntime)
			expectNoSharedLinkDep(t, ctx, binNoAsan, libAsanSharedRuntime)
			expectSharedLinkDep(t, ctx, libAsan, libAsanSharedRuntime)
			expectNoSharedLinkDep(t, ctx, libShared, libAsanSharedRuntime)
			expectNoSharedLinkDep(t, ctx, libTransitive, libAsanSharedRuntime)
		} else {
			expectNoSharedLinkDep(t, ctx, binWithAsan, libAsanSharedRuntime)
			expectNoSharedLinkDep(t, ctx, binNoAsan, libAsanSharedRuntime)
			expectNoSharedLinkDep(t, ctx, libAsan, libAsanSharedRuntime)
			expectNoSharedLinkDep(t, ctx, libShared, libAsanSharedRuntime)
			expectNoSharedLinkDep(t, ctx, libTransitive, libAsanSharedRuntime)
		}
	}

	t.Run("host", func(t *testing.T) { check(t, buildOS, RUNTIME_LINKAGE_NONE, preparer) })
	t.Run("device", func(t *testing.T) { check(t, "android_arm64_armv8-a", RUNTIME_LINKAGE_SHARED, preparer) })
	t.Run("host musl", func(t *testing.T) {
		check(t, "linux_musl_x86_64", RUNTIME_LINKAGE_SHARED,
			android.GroupFixturePreparers(preparer, PrepareForTestWithHostMusl))
	})
}

func TestTsan(t *testing.T) {
@@ -278,12 +344,14 @@ func TestTsan(t *testing.T) {
	}
`

	result := android.GroupFixturePreparers(
	preparer := android.GroupFixturePreparers(
		prepareForCcTest,
		prepareForTsanTest,
	).RunTestWithBp(t, bp)
	)
	buildOS := preparer.RunTestWithBp(t, bp).Config.BuildOSTarget.String()

	check := func(t *testing.T, result *android.TestResult, variant string) {
	check := func(t *testing.T, variant string, preparer android.FixturePreparer) {
		result := preparer.RunTestWithBp(t, bp)
		ctx := result.TestContext
		tsanVariant := variant + "_tsan"
		sharedVariant := variant + "_shared"
@@ -311,8 +379,11 @@ func TestTsan(t *testing.T) {
		expectSharedLinkDep(t, ctx, libTsan, libTransitive)
	}

	t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) })
	t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") })
	t.Run("host", func(t *testing.T) { check(t, buildOS, preparer) })
	t.Run("device", func(t *testing.T) { check(t, "android_arm64_armv8-a", preparer) })
	t.Run("host musl", func(t *testing.T) {
		check(t, "linux_musl_x86_64", android.GroupFixturePreparers(preparer, PrepareForTestWithHostMusl))
	})
}

func TestMiscUndefined(t *testing.T) {
@@ -369,11 +440,13 @@ func TestMiscUndefined(t *testing.T) {
	}
`

	result := android.GroupFixturePreparers(
	preparer := android.GroupFixturePreparers(
		prepareForCcTest,
	).RunTestWithBp(t, bp)
	)
	buildOS := preparer.RunTestWithBp(t, bp).Config.BuildOSTarget.String()

	check := func(t *testing.T, result *android.TestResult, variant string) {
	check := func(t *testing.T, variant string, preparer android.FixturePreparer) {
		result := preparer.RunTestWithBp(t, bp)
		ctx := result.TestContext
		staticVariant := variant + "_static"

@@ -415,8 +488,11 @@ func TestMiscUndefined(t *testing.T) {
		expectStaticLinkDep(t, ctx, binNoUbsan, libUbsan)
	}

	t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) })
	t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") })
	t.Run("host", func(t *testing.T) { check(t, buildOS, preparer) })
	t.Run("device", func(t *testing.T) { check(t, "android_arm64_armv8-a", preparer) })
	t.Run("host musl", func(t *testing.T) {
		check(t, "linux_musl_x86_64", android.GroupFixturePreparers(preparer, PrepareForTestWithHostMusl))
	})
}

func TestFuzz(t *testing.T) {
@@ -647,11 +723,13 @@ func TestUbsan(t *testing.T) {
		}
	`

	result := android.GroupFixturePreparers(
	preparer := android.GroupFixturePreparers(
		prepareForCcTest,
	).RunTestWithBp(t, bp)
	)
	buildOS := preparer.RunTestWithBp(t, bp).Config.BuildOSTarget.String()

	check := func(t *testing.T, result *android.TestResult, variant string) {
	check := func(t *testing.T, variant string, preparer android.FixturePreparer) {
		result := preparer.RunTestWithBp(t, bp)
		staticVariant := variant + "_static"
		sharedVariant := variant + "_shared"

@@ -705,8 +783,11 @@ func TestUbsan(t *testing.T) {
			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
	}

	t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) })
	t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") })
	t.Run("host", func(t *testing.T) { check(t, buildOS, preparer) })
	t.Run("device", func(t *testing.T) { check(t, "android_arm64_armv8-a", preparer) })
	t.Run("host musl", func(t *testing.T) {
		check(t, "linux_musl_x86_64", android.GroupFixturePreparers(preparer, PrepareForTestWithHostMusl))
	})
}

type MemtagNoteType int
+52 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ func commonDefaultModules() string {
	return `
		cc_defaults {
			name: "toolchain_libs_defaults",
			host_supported: true,
			vendor_available: true,
			product_available: true,
			recovery_available: true,
@@ -134,6 +135,12 @@ func commonDefaultModules() string {
			srcs: [""],
		}

		cc_prebuilt_library_static {
			name: "libclang_rt.ubsan_standalone.static",
			defaults: ["toolchain_libs_defaults"],
			srcs: [""],
		}

		cc_prebuilt_library_static {
			name: "libclang_rt.ubsan_minimal",
			defaults: ["toolchain_libs_defaults"],
@@ -151,6 +158,12 @@ func commonDefaultModules() string {
				linux_glibc_x86: {
					srcs: ["libclang_rt.ubsan_minimal.x86.a"],
				},
				linux_musl_x86_64: {
					srcs: ["libclang_rt.ubsan_minimal.x86_64.a"],
				},
				linux_musl_x86: {
					srcs: ["libclang_rt.ubsan_minimal.x86.a"],
				},
			},
		}

@@ -619,6 +632,45 @@ var PrepareForTestWithCcIncludeVndk = android.GroupFixturePreparers(
	}),
)

// PrepareForTestWithHostMusl sets the host configuration to musl libc instead of glibc.  It also disables the test
// on mac, which doesn't support musl libc, and adds musl modules.
var PrepareForTestWithHostMusl = android.GroupFixturePreparers(
	android.FixtureModifyConfig(android.ModifyTestConfigForMusl),
	android.PrepareForSkipTestOnMac,
	android.FixtureAddTextFile("external/musl/Android.bp", `
		cc_defaults {
			name: "libc_musl_crt_defaults",
			host_supported: true,
			device_supported: false,
		}

		cc_object {
			name: "libc_musl_crtbegin_so",
			defaults: ["libc_musl_crt_defaults"],
		}

		cc_object {
			name: "libc_musl_crtend_so",
			defaults: ["libc_musl_crt_defaults"],
		}

		cc_object {
			name: "libc_musl_crtbegin_dynamic",
			defaults: ["libc_musl_crt_defaults"],
		}

		cc_object {
			name: "libc_musl_crtbegin_static",
			defaults: ["libc_musl_crt_defaults"],
		}

		cc_object {
			name: "libc_musl_crtend",
			defaults: ["libc_musl_crt_defaults"],
		}
	`),
)

// TestConfig is the legacy way of creating a test Config for testing cc modules.
//
// See testCc for an explanation as to how to stop using this deprecated method.