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)