From patchwork Thu Nov 7 06:35:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kito Cheng X-Patchwork-Id: 2007869 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=gdN0rop9; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XkXSZ50npz1xyS for ; Thu, 7 Nov 2024 17:37:50 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D2B37385840F for ; Thu, 7 Nov 2024 06:37:48 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ot1-x334.google.com (mail-ot1-x334.google.com [IPv6:2607:f8b0:4864:20::334]) by sourceware.org (Postfix) with ESMTPS id 59C663858D3C for ; Thu, 7 Nov 2024 06:35:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 59C663858D3C Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 59C663858D3C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::334 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730961356; cv=none; b=iU8nlIAYgpGvwqjMR6C1Oj6AhiqKOxnMivm+GLyGJEWqU4E4u3ehJIV4uQjv7Jtlga9wS22y3TI+MFMNXU/2tRk7loOEW4YWGBQueXiwRmbqi3TLq1Hkh6p8k24hFKHLw39M62UmSQNqSzS6Uy/QcocZ+sxUyBpxva+fyocJgCY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730961356; c=relaxed/simple; bh=ceHdPiWu8XfkGreoSkmnxTnqfFYUhjXGOKVrzqlKwSc=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=RGt9FKv3k17dWu19Zl7ICHiXN5/RQx6QIPS7IaXiGCb27tvGTlew7R76WaeJ/rFHrESZGk/u4GYqy6/hPxeZplx2WAzjp8u3jKTQnVseE9JmHmCEXd7VJA/v37PcsPfgFTKTAD2sVchhFaIoL1klxreUhaoFikH1/xI4AYJLkTQ= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-ot1-x334.google.com with SMTP id 46e09a7af769-7180f2f5fb0so439136a34.1 for ; Wed, 06 Nov 2024 22:35:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1730961350; x=1731566150; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Evks4sAts4iQgMmOh5QfdfFG9pgYkS4vCKMu9QoqS+o=; b=gdN0rop9sa5FvE0zPtR33Im7RH4lBtBEMKqm7umy72E/IVZYqcTIAWSJvu9N5fOg14 JjdQmekZ6ANRPGyOEqcPQpY6G5Q4Xznceb4QW8tLlRtuEE1PoJ2V2uoXDpn6BLfVI0x/ ZCKWUApEiT492Z2saRS8mif4uTY+TsE7yDjDXAzH932Yq93RyjivRSvpOejBkCpGCT+4 Cdgi1G20RNjumMVE4xb86Pw+EV+wTKaz7Z2qkZtNDWtc7KbjLqDfZ1jptBbhsljtZRX2 Zlm5GMXGTwv3419opK6QDTHCcFVZ7fUUueDFK7MvBNVT5b1i1KjZXgupzeQN70mnBv3H czCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730961350; x=1731566150; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Evks4sAts4iQgMmOh5QfdfFG9pgYkS4vCKMu9QoqS+o=; b=llHk+Jum/333sYhUX/7vjpGWuAMuUTmg1m1KmOfTn8bwe0Hg9H5hz0jOYjHOZJQOqj OGYjbLRf0b/qyrxv6uNPpb8mnQUMsa6TUbYLWXf8KEHPw8MX9riWZCFYeYqx+x0GPuyN dLRuMfuBZJOX6xwk76DyHBA4u7JdjqKMadzr/E7GzZZztUbT5IqoE3GeLHmMdup0EhoP v5POnnW3GW2rUT1pBLYMedUMLMsROR39EyuhsoeHGH0Cz1/DiaLXYR/s98eD8MWhpn8F ZmtDNNwo7QG3E/mlWoIcUvQAOjYO14LiOd5/RAoXJTF5Oix2V9/43Dokz8MYi1Jl/znU ZBZQ== X-Forwarded-Encrypted: i=1; AJvYcCWgNeFWVEnR3sjoS6NtZbDOtNXspIPFIr2KP8DeAWRPAx1U9qOGzAsiyN6SwMGpOTKq3gw78oR/ZylrIg==@gcc.gnu.org X-Gm-Message-State: AOJu0YwTLSgW16PnoGU3u3FhuBgQY8kDgRZQAzJXVXpycsl9X8okD7K5 ftcNOb8iBh5Z/si7/uxegVgMLW90Qdgu45AzK8dsgIccr/Nfk37XDVw/6zL31uY= X-Google-Smtp-Source: AGHT+IH80rR8fdZuSwKJ/p577x1GkGYJHe417jzHfCI1pBYPxtK/nEciNRy5If6HlK1VtMCyO/ykIw== X-Received: by 2002:a05:6830:6009:b0:717:fe94:40af with SMTP id 46e09a7af769-71a1215a3b9mr1161513a34.3.1730961350458; Wed, 06 Nov 2024 22:35:50 -0800 (PST) Received: from hsinchu18.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7f41f5f048esm510048a12.50.2024.11.06.22.35.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Nov 2024 22:35:49 -0800 (PST) From: Kito Cheng To: Jakub Jelinek , Dodji Seketeli , Dmitry Vyukov , gcc-patches@gcc.gnu.org Cc: Kito Cheng Subject: [PATCH 2/4] libsanitizer: Apply local patches Date: Thu, 7 Nov 2024 14:35:36 +0800 Message-Id: <20241107063538.4172543-3-kito.cheng@sifive.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241107063538.4172543-1-kito.cheng@sifive.com> References: <20241107063538.4172543-1-kito.cheng@sifive.com> MIME-Version: 1.0 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org This patch just reapplies local patches (will be noted in LOCAL_PATCHES). --- libsanitizer/asan/asan_globals.cpp | 21 ------- libsanitizer/asan/asan_interceptors.h | 7 ++- libsanitizer/asan/asan_mapping.h | 2 +- .../sanitizer_linux_libcdep.cpp | 4 ++ .../sanitizer_common/sanitizer_mac.cpp | 12 +++- libsanitizer/sanitizer_common/sanitizer_mac.h | 20 ++++++ .../sanitizer_platform_limits_linux.cpp | 5 +- .../sanitizer_procmaps_mac.cpp | 62 +++---------------- .../sanitizer_redefine_builtins.h | 4 +- .../sanitizer_common/sanitizer_stacktrace.cpp | 17 +++-- libsanitizer/tsan/tsan_rtl_ppc64.S | 1 + libsanitizer/ubsan/ubsan_flags.cpp | 1 + libsanitizer/ubsan/ubsan_handlers.cpp | 15 +++++ libsanitizer/ubsan/ubsan_handlers.h | 8 +++ libsanitizer/ubsan/ubsan_handlers_cxx.cpp | 44 +++++++++++++ libsanitizer/ubsan/ubsan_handlers_cxx.h | 13 ++++ libsanitizer/ubsan/ubsan_interface.inc | 2 + libsanitizer/ubsan/ubsan_platform.h | 2 + 18 files changed, 155 insertions(+), 85 deletions(-) diff --git a/libsanitizer/asan/asan_globals.cpp b/libsanitizer/asan/asan_globals.cpp index c83b782cb85f..d1794ad96e2a 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 826b45f5ada8..652379d39a3c 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 91fe60db6329..54890ca1789b 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 525bc1038619..ed19e4031a53 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 26d2e8d4ed76..d2144546cb0f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_mac.cpp @@ -38,7 +38,7 @@ extern char **environ; # endif -# if defined(__has_include) && __has_include() +# if defined(__has_include) && __has_include() && defined(__BLOCKS__) # define SANITIZER_OS_TRACE 1 # include # else @@ -71,7 +71,15 @@ extern char ***_NSGetArgv(void); # include # include # include -# include +# if defined(__has_builtin) && __has_builtin(__builtin_os_log_format) +# include +# 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 # include # include diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_mac.h index f0a97d098eea..1cf2e298cc91 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 bf0f355847cb..c278c8797f75 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 , 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 +// struct stat:s. #include # if defined(__x86_64__) || defined(__mips__) || defined(__hexagon__) # include diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp index 5ff8d1832556..64e9c4858b69 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp @@ -146,8 +146,13 @@ static bool IsDyldHdr(const mach_header *hdr) { // 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; @@ -171,64 +176,17 @@ static mach_header *GetDyldImageHeaderViaVMRegion() { } } -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 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_redefine_builtins.h b/libsanitizer/sanitizer_common/sanitizer_redefine_builtins.h index 41e0613d6fc1..7b34e781b6d2 100644 --- a/libsanitizer/sanitizer_common/sanitizer_redefine_builtins.h +++ b/libsanitizer/sanitizer_common/sanitizer_redefine_builtins.h @@ -15,7 +15,7 @@ # define SANITIZER_REDEFINE_BUILTINS_H // The asm hack only works with GCC and Clang. -# if !defined(_WIN32) +# if !defined(_WIN32) && defined(HAVE_AS_SYM_ASSIGN) asm(R"( .set memcpy, __sanitizer_internal_memcpy @@ -52,7 +52,7 @@ using vector = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; } // namespace std # endif // __cpluplus -# endif // !_WIN32 +# endif // !_WIN32 && HAVE_AS_SYM_ASSIGN # endif // SANITIZER_REDEFINE_BUILTINS_H #endif // SANITIZER_COMMON_NO_REDEFINE_BUILTINS diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp index d24fae98213a..661495e23405 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 8285e21aa1ec..9e533a71a9c4 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 25cefd46ce27..9a66bd37518b 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 a419cf0b2b55..ea332013a50d 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 4ffa1439a132..f99948ff498f 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 206a0bb485a9..0317a3d1428c 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(calleeRTTI), + reinterpret_cast(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 71695cbdc090..f6f24e8d63ca 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 cb27feb5d7e9..f95f71af3ed1 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 d2cc2e10bd2f..ad3e883f0f35 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