Merge "Export RunBp2BuildTestCaseSimple() in testing.go"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 7a62bae..bcf335f 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -470,7 +470,6 @@
"KernelLibcutilsTest",
"linker", // TODO(b/228316882): cc_binary uses link_crt
- "libdebuggerd", // TODO(b/228314770): support product variable-specific header_libs
"versioner", // TODO(b/228313961): depends on prebuilt shared library libclang-cpp_host as a shared library, which does not supply expected providers for a shared library
"libvpx", // TODO(b/240756936): Arm neon variant not supported
"art_libartbase_headers", // TODO(b/236268577): Header libraries do not support export_shared_libs_headers
@@ -546,6 +545,7 @@
"libartbased-art-gtest", // depends on unconverted modules: libgtest_isolated, libartd, libartd-compiler, libdexfiled, libprofiled
"libartd", // depends on unconverted modules: art_operator_srcs, libcpu_features, libodrstatslog, libelffiled, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfiled, libnativebridge, libnativeloader, libsigchain, libartbased, libprofiled, cpp-define-generator-asm-support, apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api
"libartd-runtime-gtest", // depends on unconverted modules: libgtest_isolated, libartd-compiler, libdexfiled, libprofiled, libartbased, libartbased-art-gtest
+ "libdebuggerd", // depends on unconverted module: libdexfile
"libdebuggerd_handler", // depends on unconverted module libdebuggerd_handler_core
"libdebuggerd_handler_core", "libdebuggerd_handler_fallback", // depends on unconverted module libdebuggerd
"libdexfiled", // depends on unconverted modules: dexfile_operator_srcs, libartbased, libartpalette
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 45f15bf..5117c62 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -1199,6 +1199,40 @@
)
}
+func TestCcLibraryProductVariablesHeaderLibs(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Filesystem: map[string]string{},
+ Blueprint: soongCcLibraryStaticPreamble + `
+cc_library {
+ name: "foo_static",
+ srcs: ["common.c"],
+ product_variables: {
+ malloc_not_svelte: {
+ header_libs: ["malloc_not_svelte_header_lib"],
+ },
+ },
+ include_build_directory: false,
+}
+
+cc_library {
+ name: "malloc_not_svelte_header_lib",
+ bazel_module: { bp2build_available: false },
+}
+`,
+ ExpectedBazelTargets: makeCcLibraryTargets("foo_static", AttrNameToString{
+ "implementation_deps": `select({
+ "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_header_lib"],
+ "//conditions:default": [],
+ })`,
+ "srcs_c": `["common.c"]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ }),
+ },
+ )
+}
+
func TestCCLibraryNoCrtTrue(t *testing.T) {
runCcLibraryTestCase(t, Bp2buildTestCase{
Description: "cc_library - nocrt: true emits attribute",
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 77aaec1..8fb86f8 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -1026,11 +1026,17 @@
depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
}
+ // an intermediate attribute that holds Header_libs info, and will be appended to
+ // implementationDeps at the end, to solve the confliction that both header_libs
+ // and static_libs use implementationDeps.
+ var headerDeps bazel.LabelListAttribute
+
productVarToDepFields := map[string]productVarDep{
// product variables do not support exclude_shared_libs
"Shared_libs": {attribute: &la.implementationDynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
"Static_libs": {"Exclude_static_libs", &la.implementationDeps, bazelLabelForStaticDepsExcludes},
"Whole_static_libs": {"Exclude_static_libs", &la.wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
+ "Header_libs": {attribute: &headerDeps, depResolutionFunc: bazelLabelForHeaderDepsExcludes},
}
for name, dep := range productVarToDepFields {
@@ -1072,6 +1078,7 @@
)
}
}
+ la.implementationDeps.Append(headerDeps)
}
func (la *linkerAttributes) finalize(ctx android.BazelConversionPathContext) {
@@ -1200,6 +1207,12 @@
return bazelLabelForSharedDeps(ctx, modules)
}
+func bazelLabelForHeaderDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+ // This is only used when product_variable header_libs is processed, to follow
+ // the pattern of depResolutionFunc
+ return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
+}
+
func bazelLabelForSharedDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 86472a2..edff059 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -77,6 +77,7 @@
"-fno-sanitize-recover=integer,undefined"}
hwasanGlobalOptions = []string{"heap_history_size=1023", "stack_history_size=512",
"export_memory_stats=0", "max_malloc_fill_size=4096", "malloc_fill_byte=0"}
+ memtagStackCommonFlags = []string{"-march=armv8-a+memtag"}
)
type SanitizerType int
@@ -89,6 +90,7 @@
scs
Fuzzer
Memtag_heap
+ Memtag_stack
cfi // cfi is last to prevent it running before incompatible mutators
)
@@ -100,6 +102,7 @@
scs,
Fuzzer,
Memtag_heap,
+ Memtag_stack,
cfi, // cfi is last to prevent it running before incompatible mutators
}
@@ -120,6 +123,8 @@
return "scs"
case Memtag_heap:
return "memtag_heap"
+ case Memtag_stack:
+ return "memtag_stack"
case Fuzzer:
return "fuzzer"
default:
@@ -136,6 +141,8 @@
return "hwaddress"
case Memtag_heap:
return "memtag_heap"
+ case Memtag_stack:
+ return "memtag_stack"
case tsan:
return "thread"
case intOverflow:
@@ -157,7 +164,7 @@
sanitizer := &sanitizerSplitMutator{t}
ctx.TopDown(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator)
ctx.Transition(t.variationName(), sanitizer)
- case Memtag_heap, intOverflow:
+ case Memtag_heap, Memtag_stack, intOverflow:
// do nothing
default:
panic(fmt.Errorf("unknown SanitizerType %d", t))
@@ -182,6 +189,8 @@
return true
case Memtag_heap:
return true
+ case Memtag_stack:
+ return true
default:
return false
}
@@ -233,6 +242,9 @@
// Memory-tagging, only available on arm64
// if diag.memtag unset or false, enables async memory tagging
Memtag_heap *bool `android:"arch_variant"`
+ // Memory-tagging stack instrumentation, only available on arm64
+ // Adds instrumentation to detect stack buffer overflows and use-after-scope using MTE.
+ Memtag_stack *bool `android:"arch_variant"`
// A modifier for ASAN and HWASAN for write only instrumentation
Writeonly *bool `android:"arch_variant"`
@@ -318,7 +330,7 @@
return
}
- // cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap}).
+ // cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap: false}).
if ctx.testBinary() {
if s.Memtag_heap == nil {
s.Memtag_heap = proptools.BoolPtr(true)
@@ -404,6 +416,10 @@
}
}
+ if found, globalSanitizers = removeFromList("memtag_stack", globalSanitizers); found && s.Memtag_stack == nil {
+ s.Memtag_stack = proptools.BoolPtr(true)
+ }
+
if len(globalSanitizers) > 0 {
ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
}
@@ -470,14 +486,19 @@
}
// Memtag_heap is only implemented on AArch64.
- if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() {
+ // Memtag ABI is Android specific for now, so disable for host.
+ if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() || ctx.Host() {
s.Memtag_heap = nil
+ s.Memtag_stack = nil
}
// Also disable CFI if ASAN is enabled.
if Bool(s.Address) || Bool(s.Hwaddress) {
s.Cfi = nil
s.Diag.Cfi = nil
+ // HWASAN and ASAN win against MTE.
+ s.Memtag_heap = nil
+ s.Memtag_stack = nil
}
// Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
@@ -534,7 +555,7 @@
if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) ||
Bool(s.Fuzzer) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
- Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap)) {
+ Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap) || Bool(s.Memtag_stack)) {
sanitize.Properties.SanitizerEnabled = true
}
@@ -691,6 +712,20 @@
}
}
+ if Bool(sanitize.Properties.Sanitize.Memtag_stack) {
+ flags.Local.CFlags = append(flags.Local.CFlags, memtagStackCommonFlags...)
+ flags.Local.AsFlags = append(flags.Local.AsFlags, memtagStackCommonFlags...)
+ flags.Local.LdFlags = append(flags.Local.LdFlags, memtagStackCommonFlags...)
+ }
+
+ if (Bool(sanitize.Properties.Sanitize.Memtag_heap) || Bool(sanitize.Properties.Sanitize.Memtag_stack)) && ctx.binary() {
+ if Bool(sanitize.Properties.Sanitize.Diag.Memtag_heap) {
+ flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=sync")
+ } else {
+ flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=async")
+ }
+ }
+
if Bool(sanitize.Properties.Sanitize.Integer_overflow) {
flags.Local.CFlags = append(flags.Local.CFlags, intOverflowCflags...)
}
@@ -804,6 +839,8 @@
return sanitize.Properties.Sanitize.Scs
case Memtag_heap:
return sanitize.Properties.Sanitize.Memtag_heap
+ case Memtag_stack:
+ return sanitize.Properties.Sanitize.Memtag_stack
case Fuzzer:
return sanitize.Properties.Sanitize.Fuzzer
default:
@@ -819,6 +856,7 @@
!sanitize.isSanitizerEnabled(cfi) &&
!sanitize.isSanitizerEnabled(scs) &&
!sanitize.isSanitizerEnabled(Memtag_heap) &&
+ !sanitize.isSanitizerEnabled(Memtag_stack) &&
!sanitize.isSanitizerEnabled(Fuzzer)
}
@@ -850,6 +888,8 @@
sanitize.Properties.Sanitize.Scs = bPtr
case Memtag_heap:
sanitize.Properties.Sanitize.Memtag_heap = bPtr
+ case Memtag_stack:
+ sanitize.Properties.Sanitize.Memtag_stack = bPtr
case Fuzzer:
sanitize.Properties.Sanitize.Fuzzer = bPtr
default:
@@ -1311,23 +1351,11 @@
}
if Bool(c.sanitize.Properties.Sanitize.Memtag_heap) && c.Binary() {
- noteDep := "note_memtag_heap_async"
- if Bool(c.sanitize.Properties.Sanitize.Diag.Memtag_heap) {
- noteDep = "note_memtag_heap_sync"
- }
- // If we're using snapshots, redirect to snapshot whenever possible
- // TODO(b/178470649): clean manual snapshot redirections
- snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
- if lib, ok := snapshot.StaticLibs[noteDep]; ok {
- noteDep = lib
- }
- depTag := StaticDepTag(true)
- variations := append(mctx.Target().Variations(),
- blueprint.Variation{Mutator: "link", Variation: "static"})
- if c.Device() {
- variations = append(variations, c.ImageVariation())
- }
- mctx.AddFarVariationDependencies(variations, depTag, noteDep)
+ sanitizers = append(sanitizers, "memtag-heap")
+ }
+
+ if Bool(c.sanitize.Properties.Sanitize.Memtag_stack) {
+ sanitizers = append(sanitizers, "memtag-stack")
}
if Bool(c.sanitize.Properties.Sanitize.Fuzzer) {
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index 5d7e7d8..48ac650 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -344,19 +344,13 @@
func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNoteType) {
t.Helper()
- note_async := "note_memtag_heap_async"
- note_sync := "note_memtag_heap_sync"
found := None
- implicits := m.Rule("ld").Implicits
- for _, lib := range implicits {
- if strings.Contains(lib.Rel(), note_async) {
- found = Async
- break
- } else if strings.Contains(lib.Rel(), note_sync) {
- found = Sync
- break
- }
+ ldFlags := m.Rule("ld").Args["ldFlags"]
+ if strings.Contains(ldFlags, "-fsanitize-memtag-mode=async") {
+ found = Async
+ } else if strings.Contains(ldFlags, "-fsanitize-memtag-mode=sync") {
+ found = Sync
}
if found != expected {
diff --git a/cc/test.go b/cc/test.go
index 3e85e2d..28a0e5e 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -643,7 +643,6 @@
Gtest bool
Isolated bool
- Data bazel.LabelListAttribute
}
// testBinaryBp2build is the bp2build converter for cc_test modules. A cc_test's
@@ -659,6 +658,8 @@
var testBinaryAttrs testBinaryAttributes
testBinaryAttrs.binaryAttributes = binaryBp2buildAttrs(ctx, m)
+ var data bazel.LabelListAttribute
+
testBinaryProps := m.GetArchVariantProperties(ctx, &TestBinaryProperties{})
for axis, configToProps := range testBinaryProps {
for config, props := range configToProps {
@@ -668,7 +669,7 @@
combinedData.Append(android.BazelLabelForModuleSrc(ctx, p.Data))
combinedData.Append(android.BazelLabelForModuleDeps(ctx, p.Data_bins))
combinedData.Append(android.BazelLabelForModuleDeps(ctx, p.Data_libs))
- testBinaryAttrs.Data.SetSelectValue(axis, config, combinedData)
+ data.SetSelectValue(axis, config, combinedData)
}
}
}
@@ -686,6 +687,9 @@
Rule_class: "cc_test",
Bzl_load_location: "//build/bazel/rules/cc:cc_test.bzl",
},
- android.CommonAttributes{Name: m.Name()},
+ android.CommonAttributes{
+ Name: m.Name(),
+ Data: data,
+ },
&testBinaryAttrs)
}
diff --git a/java/config/config.go b/java/config/config.go
index 3ca9bad..422f860 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -148,7 +148,7 @@
pctx.SourcePathVariable("JavaKytheExtractorJar", "prebuilts/build-tools/common/framework/javac_extractor.jar")
pctx.SourcePathVariable("Ziptime", "prebuilts/build-tools/${hostPrebuiltTag}/bin/ziptime")
- pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file.py")
+ pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file")
pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh")
pctx.SourcePathVariable("PackageCheckCmd", "build/soong/scripts/package-check.sh")
diff --git a/scripts/Android.bp b/scripts/Android.bp
index 814bd57..b5b588b 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -168,7 +168,7 @@
}
python_binary_host {
- name: "gen-kotlin-build-file.py",
+ name: "gen-kotlin-build-file",
main: "gen-kotlin-build-file.py",
srcs: [
"gen-kotlin-build-file.py",
diff --git a/symbol_inject/cmd/symbol_inject.go b/symbol_inject/cmd/symbol_inject.go
index 1397b37..89b3619 100644
--- a/symbol_inject/cmd/symbol_inject.go
+++ b/symbol_inject/cmd/symbol_inject.go
@@ -94,4 +94,13 @@
os.Remove(*output)
os.Exit(5)
}
+
+ if file.IsMachoFile {
+ err = symbol_inject.CodeSignMachoFile(*output)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Remove(*output)
+ os.Exit(6)
+ }
+ }
}
diff --git a/symbol_inject/macho.go b/symbol_inject/macho.go
index 6ee3f4f..9946d34 100644
--- a/symbol_inject/macho.go
+++ b/symbol_inject/macho.go
@@ -18,6 +18,7 @@
"debug/macho"
"fmt"
"io"
+ "os/exec"
"sort"
"strings"
)
@@ -40,7 +41,7 @@
return symbols[i].Value < symbols[j].Value
})
- file := &File{}
+ file := &File{IsMachoFile: true}
for _, section := range machoFile.Sections {
file.Sections = append(file.Sections, &Section{
@@ -95,3 +96,8 @@
return nil
}
+
+func CodeSignMachoFile(path string) error {
+ cmd := exec.Command("/usr/bin/codesign", "--force", "-s", "-", path)
+ return cmd.Run()
+}
diff --git a/symbol_inject/symbol_inject.go b/symbol_inject/symbol_inject.go
index 2a3d67e..77aff6f 100644
--- a/symbol_inject/symbol_inject.go
+++ b/symbol_inject/symbol_inject.go
@@ -161,9 +161,10 @@
}
type File struct {
- r io.ReaderAt
- Symbols []*Symbol
- Sections []*Section
+ r io.ReaderAt
+ Symbols []*Symbol
+ Sections []*Section
+ IsMachoFile bool
}
type Symbol struct {