On Fri, 14 Nov 2025, Jakub Jelinek wrote:

> Hi!
> 
> Attached is a libsanitizer update.
> The attached patch (xz -9e compressed, to be applied first) is the
> result of running libsanitizer merge.sh script, the included
> patch below is a new local patch (merge of the two current
> LOCAL_PATCHES).  I had to resolve some Mac related conflicts, hope
> I got it right, but I don't have Darwin nor experience with it.
> 
> I went through abilists of all the libraries on x86_64-linux and
> all I see is some additions of symbols (except for libubsan which
> adds one new entrypoint which we don't use everything is additions
> of new intercepted routines (so some new __intercept_* and corresponding
> * exports).
> Tested on x86_64-linux and i686-linux, the only regression is
> FAIL: c-c++-common/asan/asan-stack-small.c   -O2 -flto -fno-use-linker-plugin 
> -flto-partition=none  execution test
> but that seems like the test flaw:
>   char a;
>   char b;
>   char c;
>   pa = &a;
>   pb = &b;
>   pc = &c;
>   access (pb);
>   access (pc);
>   // access 'b' here
>   access (pa + 32);
> The test assumes that the variables are laid out in the a, b, c
> order, but that is clearly not what's happening as the report is:
>   This frame has 3 object(s):
>     [32, 33) 'c' (line 16)
>     [48, 49) 'b' (line 15)
>     [64, 65) 'a' (line 14) <== Memory access at offset 96 overflows this 
> variable
> =>0x7b6566bf0000: f1 f1 f1 f1 01 f2 01 f2 01 f3 f3 f3[f3]f3 f3 f3
> So, I think the test should do something like
>   if ((uintptr_t) pb == (uintptr_t) pa + 32)
>     access (pa + 32);
>   else if ((uintptr_t) pb == (uintptr_t) pa - 32)
>     access (pa - 32);
> or so.
> 
> Iain, could you please test this on Darwin?
> 
> Ok for trunk?

LGTM besides Iains input.

Richard.

> diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp 
> b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp
> index 351e00db6fb..80ae31e938a 100644
> --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp
> +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp
> @@ -41,10 +41,18 @@ static bool FrameIsInternal(const SymbolizedStack *frame) 
> {
>      return true;
>    if (file && internal_strstr(file, "\\compiler-rt\\lib\\"))
>      return true;
> +  if (file && internal_strstr(file, "\\libsanitizer\\"))
> +    return true;
>    if (module && (internal_strstr(module, "libclang_rt.")))
>      return true;
>    if (module && (internal_strstr(module, "clang_rt.")))
>      return true;
> +  if (module && (internal_strstr(module, "libtsan.")
> +              || internal_strstr(module, "libhwasan.")
> +              || internal_strstr(module, "liblsan.")
> +              || internal_strstr(module, "libasan.")
> +              || internal_strstr(module, "libubsan.")))
> +    return true;
>    return false;
>  }
>  
> diff --git a/libsanitizer/asan/asan_globals.cpp 
> b/libsanitizer/asan/asan_globals.cpp
> index c83b782cb85..d1794ad96e2 100644
> --- a/libsanitizer/asan/asan_globals.cpp
> +++ b/libsanitizer/asan/asan_globals.cpp
> @@ -226,25 +226,6 @@ static void CheckODRViolationViaIndicator(const Global 
> *g)
>    AddGlobalToList(relevant_globals, g);
>  }
>  
> -// Check ODR violation for given global G by checking if it's already 
> poisoned.
> -// We use this method in case compiler doesn't use private aliases for global
> -// variables.
> -static void CheckODRViolationViaPoisoning(const Global *g)
> -    SANITIZER_REQUIRES(mu_for_globals) {
> -  if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {
> -    // This check may not be enough: if the first global is much larger
> -    // the entire redzone of the second global may be within the first 
> global.
> -    for (const auto &l : list_of_all_globals) {
> -      if (g->beg == l.g->beg &&
> -          (flags()->detect_odr_violation >= 2 || g->size != l.g->size) &&
> -          !IsODRViolationSuppressed(g->name)) {
> -        ReportODRViolation(g, FindRegistrationSite(g), l.g,
> -                           FindRegistrationSite(l.g));
> -      }
> -    }
> -  }
> -}
> -
>  // Clang provides two different ways for global variables protection:
>  // it can poison the global itself or its private alias. In former
>  // case we may poison same symbol multiple times, that can help us to
> @@ -290,8 +271,6 @@ static void RegisterGlobal(const Global *g) 
> SANITIZER_REQUIRES(mu_for_globals) {
>      // where two globals with the same name are defined in different modules.
>      if (UseODRIndicator(g))
>        CheckODRViolationViaIndicator(g);
> -    else
> -      CheckODRViolationViaPoisoning(g);
>    }
>    if (CanPoisonMemory())
>      PoisonRedZones(*g);
> diff --git a/libsanitizer/asan/asan_interceptors.h 
> b/libsanitizer/asan/asan_interceptors.h
> index 826b45f5ada..652379d39a3 100644
> --- a/libsanitizer/asan/asan_interceptors.h
> +++ b/libsanitizer/asan/asan_interceptors.h
> @@ -71,7 +71,12 @@ void InitializePlatformInterceptors();
>  #if ASAN_HAS_EXCEPTIONS && !SANITIZER_SOLARIS && !SANITIZER_NETBSD && \
>      (!SANITIZER_WINDOWS || (defined(__MINGW32__) && defined(__i386__)))
>  # define ASAN_INTERCEPT___CXA_THROW 1
> -# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
> +# if ! defined(ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION) \
> +     || ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION
> +#   define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
> +# else
> +#   define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0
> +# endif
>  # if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__))
>  #  define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1
>  # else
> diff --git a/libsanitizer/asan/asan_mapping.h 
> b/libsanitizer/asan/asan_mapping.h
> index 91fe60db632..54890ca1789 100644
> --- a/libsanitizer/asan/asan_mapping.h
> +++ b/libsanitizer/asan/asan_mapping.h
> @@ -193,7 +193,7 @@
>  #  elif defined(__aarch64__)
>  #    define ASAN_SHADOW_OFFSET_CONST 0x0000001000000000
>  #  elif defined(__powerpc64__)
> -#    define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000
> +#    define ASAN_SHADOW_OFFSET_CONST 0x0000020000000000
>  #  elif defined(__s390x__)
>  #    define ASAN_SHADOW_OFFSET_CONST 0x0010000000000000
>  #  elif SANITIZER_FREEBSD
> diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp 
> b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
> index 525bc103861..ed19e4031a5 100644
> --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
> +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
> @@ -901,9 +901,13 @@ u32 GetNumberOfCPUs() {
>  #  elif SANITIZER_SOLARIS
>    return sysconf(_SC_NPROCESSORS_ONLN);
>  #  else
> +#    if defined(CPU_COUNT)
>    cpu_set_t CPUs;
>    CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0);
>    return CPU_COUNT(&CPUs);
> +#    else
> +  return 1;
> +#    endif
>  #  endif
>  }
>  
> diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cpp 
> b/libsanitizer/sanitizer_common/sanitizer_mac.cpp
> index 26d2e8d4ed7..d2144546cb0 100644
> --- a/libsanitizer/sanitizer_common/sanitizer_mac.cpp
> +++ b/libsanitizer/sanitizer_common/sanitizer_mac.cpp
> @@ -71,7 +71,15 @@ extern char ***_NSGetArgv(void);
>  #  include <mach/mach_time.h>
>  #  include <mach/vm_statistics.h>
>  #  include <malloc/malloc.h>
> -#  include <os/log.h>
> +#  if defined(__has_builtin) && __has_builtin(__builtin_os_log_format)
> +#    include <os/log.h>
> +#  else
> +     /* Without support for __builtin_os_log_format, fall back to the older
> +        method.  */
> +#    define OS_LOG_DEFAULT 0
> +#    define os_log_error(A,B,C) \
> +       asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", (C));
> +#  endif
>  #  include <pthread.h>
>  #  include <pthread/introspection.h>
>  #  include <sched.h>
> diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h 
> b/libsanitizer/sanitizer_common/sanitizer_mac.h
> index f0a97d098ee..1cf2e298cc9 100644
> --- a/libsanitizer/sanitizer_common/sanitizer_mac.h
> +++ b/libsanitizer/sanitizer_common/sanitizer_mac.h
> @@ -14,6 +14,26 @@
>  
>  #include "sanitizer_common.h"
>  #include "sanitizer_platform.h"
> +
> +/* TARGET_OS_OSX is not present in SDKs before Darwin16 (macOS 10.12) use
> +   TARGET_OS_MAC (we have no support for iOS in any form for these versions,
> +   so there's no ambiguity).  */
> +#if !defined(TARGET_OS_OSX) && TARGET_OS_MAC
> +# define TARGET_OS_OSX 1
> +#endif
> +
> +/* Other TARGET_OS_xxx are not present on earlier versions, define them to
> +   0 (we have no support for them; they are not valid targets anyway).  */
> +#ifndef TARGET_OS_IOS
> +#define TARGET_OS_IOS 0
> +#endif
> +#ifndef TARGET_OS_TV
> +#define TARGET_OS_TV 0
> +#endif
> +#ifndef TARGET_OS_WATCH
> +#define TARGET_OS_WATCH 0
> +#endif
> +
>  #if SANITIZER_APPLE
>  #include "sanitizer_posix.h"
>  
> diff --git 
> a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp 
> b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp
> index bf0f355847c..c278c8797f7 100644
> --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp
> +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp
> @@ -26,7 +26,10 @@
>  
>  // With old kernels (and even new kernels on powerpc) asm/stat.h uses types 
> that
>  // are not defined anywhere in userspace headers. Fake them. This seems to 
> work
> -// fine with newer headers, too.
> +// fine with newer headers, too.  Beware that with <sys/stat.h>, struct stat
> +// takes the form of struct stat64 on 32-bit platforms if 
> _FILE_OFFSET_BITS=64.
> +// Also, for some platforms (e.g. mips) there are additional members in the
> +// <sys/stat.h> struct stat:s.
>  #include <linux/posix_types.h>
>  #  if defined(__x86_64__) || defined(__mips__) || defined(__hexagon__)
>  #    include <sys/stat.h>
> diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp 
> b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
> index 5ff8d183255..64e9c4858b6 100644
> --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
> +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
> @@ -197,8 +197,13 @@ static bool IsDyldHdr(const mach_header
>  // until we hit a Mach header matching dyld instead. These recurse
>  // calls are expensive, but the first memory map generation occurs
>  // early in the process, when dyld is one of the only images loaded,
> -// so it will be hit after only a few iterations.  These assumptions don't 
> hold
> -// on macOS 13+ anymore (dyld itself has moved into the shared cache).
> +// so it will be hit after only a few iterations.  These assumptions don't
> +// hold on macOS 13+ anymore (dyld itself has moved into the shared cache).
> +
> +// FIXME: Unfortunately, the upstream revised version to deal with macOS 13+
> +// is incompatible with GCC and also uses APIs not available on earlier
> +// systems which we support; backed out for now.
> +
>  static mach_header *GetDyldImageHeaderViaVMRegion() {
>    vm_address_t address = 0;
>  
> @@ -222,65 +227,17 @@ static mach_header *GetDyldImageHeaderVi
>    }
>  }
>  
> -extern "C" {
> -struct dyld_shared_cache_dylib_text_info {
> -  uint64_t version;  // current version 2
> -  // following fields all exist in version 1
> -  uint64_t loadAddressUnslid;
> -  uint64_t textSegmentSize;
> -  uuid_t dylibUuid;
> -  const char *path;  // pointer invalid at end of iterations
> -  // following fields all exist in version 2
> -  uint64_t textSegmentOffset;  // offset from start of cache
> -};
> -typedef struct dyld_shared_cache_dylib_text_info
> -    dyld_shared_cache_dylib_text_info;
> -
> -extern bool _dyld_get_shared_cache_uuid(uuid_t uuid);
> -extern const void *_dyld_get_shared_cache_range(size_t *length);
> -extern intptr_t _dyld_get_image_slide(const struct mach_header* mh);
> -extern int dyld_shared_cache_iterate_text(
> -    const uuid_t cacheUuid,
> -    void (^callback)(const dyld_shared_cache_dylib_text_info *info));
> -}  // extern "C"
> -
> -static mach_header *GetDyldImageHeaderViaSharedCache() {
> -  uuid_t uuid;
> -  bool hasCache = _dyld_get_shared_cache_uuid(uuid);
> -  if (!hasCache)
> -    return nullptr;
> -
> -  size_t cacheLength;
> -  __block uptr cacheStart = (uptr)_dyld_get_shared_cache_range(&cacheLength);
> -  CHECK(cacheStart && cacheLength);
> -
> -  __block mach_header *dyldHdr = nullptr;
> -  int res = dyld_shared_cache_iterate_text(
> -      uuid, ^(const dyld_shared_cache_dylib_text_info *info) {
> -        CHECK_GE(info->version, 2);
> -        mach_header *hdr =
> -            (mach_header *)(cacheStart + info->textSegmentOffset);
> -        if (IsDyldHdr(hdr))
> -          dyldHdr = hdr;
> -      });
> -  CHECK_EQ(res, 0);
> -
> -  return dyldHdr;
> -}
> -
>  const mach_header *get_dyld_hdr() {
>    if (!dyld_hdr) {
>      // On macOS 13+, dyld itself has moved into the shared cache.  Looking 
> it up
>      // via vm_region_recurse_64() causes spins/hangs/crashes.
> +    // FIXME: find a way to do this compatible with GCC.
>      if (GetMacosAlignedVersion() >= MacosVersion(13, 0)) {
> -      dyld_hdr = GetDyldImageHeaderViaSharedCache();
> -      if (!dyld_hdr) {
>          VReport(1,
> -                "Failed to lookup the dyld image header in the shared cache 
> on "
> -                "macOS 13+ (or no shared cache in use).  Falling back to "
> +                "looking up the dyld image header in the shared cache on "
> +                "macOS 13+ is not yet supported.  Falling back to "
>                  "lookup via vm_region_recurse_64().\n");
>          dyld_hdr = GetDyldImageHeaderViaVMRegion();
> -      }
>      } else {
>        dyld_hdr = GetDyldImageHeaderViaVMRegion();
>      }
> diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp 
> b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp
> index d24fae98213..661495e2340 100644
> --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp
> +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp
> @@ -87,8 +87,8 @@ static inline uhwptr *GetCanonicFrame(uptr bp,
>    // Nope, this does not look right either. This means the frame after next 
> does
>    // not have a valid frame pointer, but we can still extract the caller PC.
>    // Unfortunately, there is no way to decide between GCC and LLVM frame
> -  // layouts. Assume LLVM.
> -  return bp_prev;
> +  // layouts. Assume GCC.
> +  return bp_prev - 1;
>  #else
>    return (uhwptr*)bp;
>  #endif
> @@ -111,14 +111,21 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, 
> uptr stack_top,
>           IsAligned((uptr)frame, sizeof(*frame)) &&
>           size < max_depth) {
>  #ifdef __powerpc__
> -    // PowerPC ABIs specify that the return address is saved at offset
> -    // 16 of the *caller's* stack frame.  Thus we must dereference the
> -    // back chain to find the caller frame before extracting it.
> +    // PowerPC ABIs specify that the return address is saved on the
> +    // *caller's* stack frame.  Thus we must dereference the back chain
> +    // to find the caller frame before extracting it.
>      uhwptr *caller_frame = (uhwptr*)frame[0];
>      if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) ||
>          !IsAligned((uptr)caller_frame, sizeof(uhwptr)))
>        break;
> +    // For most ABIs the offset where the return address is saved is two
> +    // register sizes.  The exception is the SVR4 ABI, which uses an
> +    // offset of only one register size.
> +#ifdef _CALL_SYSV
> +    uhwptr pc1 = caller_frame[1];
> +#else
>      uhwptr pc1 = caller_frame[2];
> +#endif
>  #elif defined(__s390__)
>      uhwptr pc1 = frame[14];
>  #elif defined(__loongarch__) || defined(__riscv)
> diff --git a/libsanitizer/tsan/tsan_rtl_ppc64.S 
> b/libsanitizer/tsan/tsan_rtl_ppc64.S
> index 8285e21aa1e..9e533a71a9c 100644
> --- a/libsanitizer/tsan/tsan_rtl_ppc64.S
> +++ b/libsanitizer/tsan/tsan_rtl_ppc64.S
> @@ -1,5 +1,6 @@
>  #include "tsan_ppc_regs.h"
>  
> +        .machine altivec
>          .section .text
>          .hidden __tsan_setjmp
>          .globl _setjmp
> diff --git a/libsanitizer/ubsan/ubsan_flags.cpp 
> b/libsanitizer/ubsan/ubsan_flags.cpp
> index 25cefd46ce2..9a66bd37518 100644
> --- a/libsanitizer/ubsan/ubsan_flags.cpp
> +++ b/libsanitizer/ubsan/ubsan_flags.cpp
> @@ -50,6 +50,7 @@ void InitializeFlags() {
>    {
>      CommonFlags cf;
>      cf.CopyFrom(*common_flags());
> +    cf.print_summary = false;
>      cf.external_symbolizer_path = GetFlag("UBSAN_SYMBOLIZER_PATH");
>      OverrideCommonFlags(cf);
>    }
> diff --git a/libsanitizer/ubsan/ubsan_handlers.cpp 
> b/libsanitizer/ubsan/ubsan_handlers.cpp
> index a419cf0b2b5..ea332013a50 100644
> --- a/libsanitizer/ubsan/ubsan_handlers.cpp
> +++ b/libsanitizer/ubsan/ubsan_handlers.cpp
> @@ -904,6 +904,21 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, 
> ValueHandle Vtable,
>  
>  }  // namespace __ubsan
>  
> +void __ubsan::__ubsan_handle_cfi_bad_icall(CFIBadIcallData *CallData,
> +                                           ValueHandle Function) {
> +  GET_REPORT_OPTIONS(false);
> +  CFICheckFailData Data = {CFITCK_ICall, CallData->Loc, CallData->Type};
> +  handleCFIBadIcall(&Data, Function, Opts);
> +}
> +
> +void __ubsan::__ubsan_handle_cfi_bad_icall_abort(CFIBadIcallData *CallData,
> +                                                 ValueHandle Function) {
> +  GET_REPORT_OPTIONS(true);
> +  CFICheckFailData Data = {CFITCK_ICall, CallData->Loc, CallData->Type};
> +  handleCFIBadIcall(&Data, Function, Opts);
> +  Die();
> +}
> +
>  void __ubsan::__ubsan_handle_cfi_check_fail(CFICheckFailData *Data,
>                                              ValueHandle Value,
>                                              uptr ValidVtable) {
> diff --git a/libsanitizer/ubsan/ubsan_handlers.h 
> b/libsanitizer/ubsan/ubsan_handlers.h
> index 4ffa1439a13..f99948ff498 100644
> --- a/libsanitizer/ubsan/ubsan_handlers.h
> +++ b/libsanitizer/ubsan/ubsan_handlers.h
> @@ -217,12 +217,20 @@ enum CFITypeCheckKind : unsigned char {
>    CFITCK_VMFCall,
>  };
>  
> +struct CFIBadIcallData {
> +  SourceLocation Loc;
> +  const TypeDescriptor &Type;
> +};
> +
>  struct CFICheckFailData {
>    CFITypeCheckKind CheckKind;
>    SourceLocation Loc;
>    const TypeDescriptor &Type;
>  };
>  
> +/// \brief Handle control flow integrity failure for indirect function calls.
> +RECOVERABLE(cfi_bad_icall, CFIBadIcallData *Data, ValueHandle Function)
> +
>  /// \brief Handle control flow integrity failures.
>  RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function,
>              uptr VtableIsValid)
> diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.cpp 
> b/libsanitizer/ubsan/ubsan_handlers_cxx.cpp
> index 206a0bb485a..0317a3d1428 100644
> --- a/libsanitizer/ubsan/ubsan_handlers_cxx.cpp
> +++ b/libsanitizer/ubsan/ubsan_handlers_cxx.cpp
> @@ -156,6 +156,50 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, 
> ValueHandle Vtable,
>      Diag(Loc, DL_Note, ET, "check failed in %0, vtable located in %1")
>          << SrcModule << DstModule;
>  }
> +
> +static bool handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
> +                                       ValueHandle Function,
> +                                       ValueHandle calleeRTTI,
> +                                       ValueHandle fnRTTI, ReportOptions 
> Opts) {
> +  if (checkTypeInfoEquality(reinterpret_cast<void *>(calleeRTTI),
> +                            reinterpret_cast<void *>(fnRTTI)))
> +    return false;
> +
> +  SourceLocation CallLoc = Data->Loc.acquire();
> +  ErrorType ET = ErrorType::FunctionTypeMismatch;
> +
> +  if (ignoreReport(CallLoc, Opts, ET))
> +    return true;
> +
> +  ScopedReport R(Opts, CallLoc, ET);
> +
> +  SymbolizedStackHolder FLoc(getSymbolizedLocation(Function));
> +  const char *FName = FLoc.get()->info.function;
> +  if (!FName)
> +    FName = "(unknown)";
> +
> +  Diag(CallLoc, DL_Error, ET,
> +       "call to function %0 through pointer to incorrect function type %1")
> +      << FName << Data->Type;
> +  Diag(FLoc, DL_Note, ET, "%0 defined here") << FName;
> +  return true;
> +}
> +
> +void __ubsan_handle_function_type_mismatch_v1(FunctionTypeMismatchData *Data,
> +                                              ValueHandle Function,
> +                                              ValueHandle calleeRTTI,
> +                                              ValueHandle fnRTTI) {
> +  GET_REPORT_OPTIONS(false);
> +  handleFunctionTypeMismatch(Data, Function, calleeRTTI, fnRTTI, Opts);
> +}
> +
> +void __ubsan_handle_function_type_mismatch_v1_abort(
> +    FunctionTypeMismatchData *Data, ValueHandle Function,
> +    ValueHandle calleeRTTI, ValueHandle fnRTTI) {
> +  GET_REPORT_OPTIONS(true);
> +  if (handleFunctionTypeMismatch(Data, Function, calleeRTTI, fnRTTI, Opts))
> +    Die();
> +}
>  }  // namespace __ubsan
>  
>  #endif // CAN_SANITIZE_UB
> diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.h 
> b/libsanitizer/ubsan/ubsan_handlers_cxx.h
> index 71695cbdc09..f6f24e8d63c 100644
> --- a/libsanitizer/ubsan/ubsan_handlers_cxx.h
> +++ b/libsanitizer/ubsan/ubsan_handlers_cxx.h
> @@ -33,6 +33,19 @@ void __ubsan_handle_dynamic_type_cache_miss(
>  extern "C" SANITIZER_INTERFACE_ATTRIBUTE
>  void __ubsan_handle_dynamic_type_cache_miss_abort(
>    DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
> +
> +struct FunctionTypeMismatchData;
> +
> +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
> +__ubsan_handle_function_type_mismatch_v1(FunctionTypeMismatchData *Data,
> +                                         ValueHandle Val,
> +                                         ValueHandle calleeRTTI,
> +                                         ValueHandle fnRTTI);
> +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
> +__ubsan_handle_function_type_mismatch_v1_abort(FunctionTypeMismatchData 
> *Data,
> +                                               ValueHandle Val,
> +                                               ValueHandle calleeRTTI,
> +                                               ValueHandle fnRTTI);
>  }
>  
>  #endif // UBSAN_HANDLERS_CXX_H
> diff --git a/libsanitizer/ubsan/ubsan_interface.inc 
> b/libsanitizer/ubsan/ubsan_interface.inc
> index cb27feb5d7e..f95f71af3ed 100644
> --- a/libsanitizer/ubsan/ubsan_interface.inc
> +++ b/libsanitizer/ubsan/ubsan_interface.inc
> @@ -21,6 +21,8 @@ INTERFACE_FUNCTION(__ubsan_handle_dynamic_type_cache_miss)
>  INTERFACE_FUNCTION(__ubsan_handle_dynamic_type_cache_miss_abort)
>  INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow)
>  INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow_abort)
> +INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1)
> +INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1_abort)
>  INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch)
>  INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_abort)
>  INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion)
> diff --git a/libsanitizer/ubsan/ubsan_platform.h 
> b/libsanitizer/ubsan/ubsan_platform.h
> index d2cc2e10bd2..ad3e883f0f3 100644
> --- a/libsanitizer/ubsan/ubsan_platform.h
> +++ b/libsanitizer/ubsan/ubsan_platform.h
> @@ -12,6 +12,7 @@
>  #ifndef UBSAN_PLATFORM_H
>  #define UBSAN_PLATFORM_H
>  
> +#ifndef CAN_SANITIZE_UB
>  // Other platforms should be easy to add, and probably work as-is.
>  #if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) ||      
>   \
>      defined(__NetBSD__) || defined(__DragonFly__) ||                         
>   \
> @@ -21,5 +22,6 @@
>  #else
>  # define CAN_SANITIZE_UB 0
>  #endif
> +#endif //CAN_SANITIZE_UB
>  
>  #endif
> 
> 
>       Jakub
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to