diff options
author | Evgenii Stepanov <eugenis@google.com> | 2016-08-16 15:39:54 -0700 |
---|---|---|
committer | Evgenii Stepanov <eugenis@google.com> | 2016-10-31 15:29:08 -0700 |
commit | 1e405e160aafca31f15f0d20e00bbe6e346a3d1a (patch) | |
tree | b1ee2976d481ddc5963066c111fa055321acb6f7 /cc/sanitize.go | |
parent | 5d5db02bf6cd527455abcbf3502e990bb2d21e5a (diff) | |
download | build_soong-1e405e160aafca31f15f0d20e00bbe6e346a3d1a.tar.gz build_soong-1e405e160aafca31f15f0d20e00bbe6e346a3d1a.tar.bz2 build_soong-1e405e160aafca31f15f0d20e00bbe6e346a3d1a.zip |
[soong] Enable LOCAL_SANITIZE:=cfi and add LOCAL_SANITIZE_DIAG.
LOCAL_SANITIZE_DIAG works for ubsan, too.
Bug: 22033465
Test: build a test target with cfi and diag { cfi } properties.
Change-Id: I9cd8e8df9b330430b321709d7f05b4da0294e771
Diffstat (limited to 'cc/sanitize.go')
-rw-r--r-- | cc/sanitize.go | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/cc/sanitize.go b/cc/sanitize.go index d9e28ccb..8d162e77 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -71,8 +71,17 @@ type SanitizeProperties struct { Misc_undefined []string `android:"arch_variant"` Coverage *bool `android:"arch_variant"` Safestack *bool `android:"arch_variant"` + Cfi *bool `android:"arch_variant"` + + // Sanitizers to run in the diagnostic mode (as opposed to the release mode). + // Replaces abort() on error with a human-readable error message. + // Address and Thread sanitizers always run in diagnostic mode. + Diag struct { + Undefined *bool `android:"arch_variant"` + Cfi *bool `android:"arch_variant"` + } - // value to pass to -fsantitize-recover= + // value to pass to -fsanitize-recover= Recover []string // value to pass to -fsanitize-blacklist @@ -140,6 +149,10 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { s.Safestack = boolPtr(true) } + if found, globalSanitizers = removeFromList("cfi", globalSanitizers); found && s.Cfi == nil { + s.Cfi = boolPtr(true) + } + if len(globalSanitizers) > 0 { ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0]) } @@ -163,7 +176,7 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { } if Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || - Bool(s.Thread) || Bool(s.Coverage) || Bool(s.Safestack) { + Bool(s.Thread) || Bool(s.Coverage) || Bool(s.Safestack) || Bool(s.Cfi) { sanitize.Properties.SanitizerEnabled = true } @@ -201,6 +214,7 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { } var sanitizers []string + var diagSanitizers []string if Bool(sanitize.Properties.Sanitize.All_undefined) { sanitizers = append(sanitizers, "undefined") @@ -236,6 +250,13 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { sanitizers = append(sanitizers, sanitize.Properties.Sanitize.Misc_undefined...) } + if Bool(sanitize.Properties.Sanitize.Diag.Undefined) && + (Bool(sanitize.Properties.Sanitize.All_undefined) || + Bool(sanitize.Properties.Sanitize.Undefined) || + len(sanitize.Properties.Sanitize.Misc_undefined) > 0) { + diagSanitizers = append(diagSanitizers, "undefined") + } + if Bool(sanitize.Properties.Sanitize.Address) { if ctx.Arch().ArchType == android.Arm { // Frame pointer based unwinder in ASan requires ARM frame setup. @@ -266,6 +287,7 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { } } sanitizers = append(sanitizers, "address") + diagSanitizers = append(diagSanitizers, "address") } if Bool(sanitize.Properties.Sanitize.Coverage) { @@ -276,6 +298,19 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { sanitizers = append(sanitizers, "safe-stack") } + if Bool(sanitize.Properties.Sanitize.Cfi) { + sanitizers = append(sanitizers, "cfi") + cfiFlags := []string{"-flto", "-fsanitize=cfi", "-fsanitize-cfi-cross-dso"} + flags.CFlags = append(flags.CFlags, cfiFlags...) + flags.CFlags = append(flags.CFlags, "-fvisibility=default") + flags.LdFlags = append(flags.LdFlags, cfiFlags...) + // FIXME: revert the __cfi_check flag when clang is updated to r280031. + flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,O1", "-Wl,-export-dynamic-symbol=__cfi_check") + if Bool(sanitize.Properties.Sanitize.Diag.Cfi) { + diagSanitizers = append(diagSanitizers, "cfi") + } + } + if sanitize.Properties.Sanitize.Recover != nil { flags.CFlags = append(flags.CFlags, "-fsanitize-recover="+ strings.Join(sanitize.Properties.Sanitize.Recover, ",")) @@ -290,12 +325,27 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { flags.LdFlags = append(flags.LdFlags, "-lrt", "-ldl") } else { flags.CFlags = append(flags.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort") - if Bool(sanitize.Properties.Sanitize.Address) || Bool(sanitize.Properties.Sanitize.Thread) { - flags.CFlags = append(flags.CFlags, "-fno-sanitize-trap=address,thread") - } } } + if len(diagSanitizers) > 0 { + flags.CFlags = append(flags.CFlags, "-fno-sanitize-trap="+strings.Join(diagSanitizers, ",")) + } + // FIXME: enable RTTI if diag + (cfi or vptr) + + // Link a runtime library if needed. + runtimeLibrary := "" + if Bool(sanitize.Properties.Sanitize.Address) { + runtimeLibrary = config.AddressSanitizerRuntimeLibrary(ctx.toolchain()) + } else if len(diagSanitizers) > 0 { + runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(ctx.toolchain()) + } + + // ASan runtime library must be the first in the link order. + if runtimeLibrary != "" { + flags.libFlags = append([]string{"${config.ClangAsanLibDir}/" + runtimeLibrary}, flags.libFlags...) + } + blacklist := android.OptionalPathForModuleSrc(ctx, sanitize.Properties.Sanitize.Blacklist) if blacklist.Valid() { flags.CFlags = append(flags.CFlags, "-fsanitize-blacklist="+blacklist.String()) |