Home | History | Annotate | Download | only in core
      1 ##############################################
      2 ## Perform configuration steps for sanitizers.
      3 ##############################################
      4 
      5 my_sanitize := $(strip $(LOCAL_SANITIZE))
      6 
      7 # SANITIZE_HOST is only in effect if the module is already using clang (host
      8 # modules that haven't set `LOCAL_CLANG := false` and device modules that
      9 # have set `LOCAL_CLANG := true`.
     10 my_global_sanitize :=
     11 ifeq ($(my_clang),true)
     12   ifdef LOCAL_IS_HOST_MODULE
     13     my_global_sanitize := $(strip $(SANITIZE_HOST))
     14 
     15     # SANITIZE_HOST=true is a deprecated way to say SANITIZE_HOST=address.
     16     my_global_sanitize := $(subst true,address,$(my_global_sanitize))
     17   else
     18     my_global_sanitize := $(strip $(SANITIZE_TARGET))
     19   endif
     20 endif
     21 
     22 # The sanitizer specified by the environment wins over the module.
     23 ifneq ($(my_global_sanitize),)
     24   my_sanitize := $(my_global_sanitize)
     25 endif
     26 
     27 # The sanitizer specified in the product configuration wins over the previous.
     28 ifneq ($(SANITIZER.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG),)
     29   my_sanitize := $(SANITIZER.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG)
     30   ifeq ($(my_sanitize),never)
     31     my_sanitize :=
     32   endif
     33 endif
     34 
     35 # Add a filter point for 32-bit vs 64-bit sanitization (to lighten the burden).
     36 SANITIZE_ARCH ?= 32 64
     37 ifeq ($(filter $(SANITIZE_ARCH),$(my_32_64_bit_suffix)),)
     38   my_sanitize :=
     39 endif
     40 
     41 # Add a filter point based on module owner (to lighten the burden). The format is a space- or
     42 # colon-separated list of owner names.
     43 ifneq (,$(SANITIZE_NEVER_BY_OWNER))
     44   ifneq (,$(LOCAL_MODULE_OWNER))
     45     ifneq (,$(filter $(LOCAL_MODULE_OWNER),$(subst :, ,$(SANITIZE_NEVER_BY_OWNER))))
     46       $(warning Not sanitizing $(LOCAL_MODULE) based on module owner.)
     47       my_sanitize :=
     48     endif
     49   endif
     50 endif
     51 
     52 # Don't apply sanitizers to NDK code.
     53 ifdef LOCAL_SDK_VERSION
     54   my_sanitize :=
     55 endif
     56 
     57 # Never always wins.
     58 ifeq ($(LOCAL_SANITIZE),never)
     59   my_sanitize :=
     60 endif
     61 
     62 # TSAN is not supported on 32-bit architectures. For non-multilib cases, make
     63 # its use an error. For multilib cases, don't use it for the 32-bit case.
     64 ifneq ($(filter thread,$(my_sanitize)),)
     65   ifeq ($(my_32_64_bit_suffix),32)
     66     ifeq ($(my_module_multilib),both)
     67         my_sanitize := $(filter-out thread,$(my_sanitize))
     68     else
     69         $(error $(LOCAL_PATH): $(LOCAL_MODULE): TSAN cannot be used for 32-bit modules.)
     70     endif
     71   endif
     72 endif
     73 
     74 # Undefined symbols can occur if a non-sanitized library links
     75 # sanitized static libraries. That's OK, because the executable
     76 # always depends on the ASan runtime library, which defines these
     77 # symbols.
     78 ifneq ($(strip $(SANITIZE_TARGET)),)
     79   ifndef LOCAL_IS_HOST_MODULE
     80     ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
     81       ifeq ($(my_sanitize),)
     82         my_allow_undefined_symbols := true
     83       endif
     84     endif
     85     # Workaround for a bug in AddressSanitizer that breaks stack unwinding.
     86     # https://code.google.com/p/address-sanitizer/issues/detail?id=387
     87     # Revert when external/compiler-rt is updated past r236014.
     88     LOCAL_PACK_MODULE_RELOCATIONS := false
     89   endif
     90 endif
     91 
     92 # Sanitizers can only be used with clang.
     93 ifneq ($(my_clang),true)
     94   ifneq ($(my_sanitize),)
     95     $(error $(LOCAL_PATH): $(LOCAL_MODULE): Use of sanitizers requires LOCAL_CLANG := true)
     96   endif
     97 endif
     98 
     99 ifneq ($(filter default-ub,$(my_sanitize)),)
    100   my_sanitize := $(CLANG_DEFAULT_UB_CHECKS)
    101 endif
    102 
    103 ifneq ($(filter coverage,$(my_sanitize)),)
    104   ifeq ($(filter address,$(my_sanitize)),)
    105     $(error $(LOCAL_PATH): $(LOCAL_MODULE): Use of 'coverage' also requires 'address')
    106   endif
    107   my_cflags += -fsanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp
    108   my_sanitize := $(filter-out coverage,$(my_sanitize))
    109 endif
    110 
    111 ifneq ($(my_sanitize),)
    112   fsanitize_arg := $(subst $(space),$(comma),$(my_sanitize))
    113   my_cflags += -fsanitize=$(fsanitize_arg)
    114 
    115   ifdef LOCAL_IS_HOST_MODULE
    116     my_cflags += -fno-sanitize-recover=all
    117     my_ldflags += -fsanitize=$(fsanitize_arg)
    118     my_ldlibs += -lrt -ldl
    119   else
    120     ifeq ($(filter address,$(my_sanitize)),)
    121       my_cflags += -fsanitize-trap=all
    122       my_cflags += -ftrap-function=abort
    123     endif
    124     my_shared_libraries += libdl
    125   endif
    126 endif
    127 
    128 ifneq ($(filter address,$(my_sanitize)),)
    129   # Frame pointer based unwinder in ASan requires ARM frame setup.
    130   LOCAL_ARM_MODE := arm
    131   my_cflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
    132   my_ldflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS)
    133   ifdef LOCAL_IS_HOST_MODULE
    134     # -nodefaultlibs (provided with libc++) prevents the driver from linking
    135     # libraries needed with -fsanitize=address. http://b/18650275 (WAI)
    136     my_ldlibs += -lm -lpthread
    137     my_ldflags += -Wl,--no-as-needed
    138   else
    139     my_cflags += -mllvm -asan-globals=0
    140     # ASan runtime library must be the first in the link order.
    141     my_shared_libraries := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY) \
    142                            $(my_shared_libraries) \
    143                            $(ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES)
    144     my_static_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES)
    145 
    146     my_linker := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER)
    147     # Make sure linker_asan get installed.
    148     $(LOCAL_INSTALLED_MODULE) : | $(PRODUCT_OUT)$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER)
    149   endif
    150 endif
    151 
    152 ifneq ($(filter undefined,$(my_sanitize)),)
    153   ifndef LOCAL_IS_HOST_MODULE
    154     $(error ubsan is not yet supported on the target)
    155   endif
    156 endif
    157 
    158 ifneq ($(strip $(LOCAL_SANITIZE_RECOVER)),)
    159   recover_arg := $(subst $(space),$(comma),$(LOCAL_SANITIZE_RECOVER)),
    160   my_cflags += -fsanitize-recover=$(recover_arg)
    161 endif
    162