https://gcc.gnu.org/g:89130a50108077e81a11a60007de6830c9f23b34

commit r16-5832-g89130a50108077e81a11a60007de6830c9f23b34
Author: Jakub Jelinek <[email protected]>
Date:   Tue Dec 2 13:05:12 2025 +0100

    Reapply all revisions mentioned in LOCAL_PATCHES except for Darwin related 
stuff.

Diff:
---
 libsanitizer/asan/asan_globals.cpp                 | 21 -----------
 libsanitizer/asan/asan_interceptors.h              |  7 +++-
 libsanitizer/asan/asan_mapping.h                   |  2 +-
 .../sanitizer_common/sanitizer_linux_libcdep.cpp   |  4 ++
 .../sanitizer_platform_limits_linux.cpp            |  5 ++-
 .../sanitizer_common/sanitizer_stacktrace.cpp      | 17 ++++++---
 .../sanitizer_symbolizer_report.cpp                |  8 ++++
 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 +
 15 files changed, 121 insertions(+), 29 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 2d551cfafd1f..6efc20245167 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 bddae9a07405..b10e04733dfc 100644
--- a/libsanitizer/asan/asan_mapping.h
+++ b/libsanitizer/asan/asan_mapping.h
@@ -204,7 +204,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 530ff90c4cd1..2b4934be0aa4 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -849,9 +849,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_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 <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_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/sanitizer_common/sanitizer_symbolizer_report.cpp 
b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp
index 351e00db6fb2..80ae31e938ae 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/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 63319f46734a..be55ee5a3119 100644
--- a/libsanitizer/ubsan/ubsan_handlers.cpp
+++ b/libsanitizer/ubsan/ubsan_handlers.cpp
@@ -920,6 +920,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 521caa96bc77..b6df110f87ec 100644
--- a/libsanitizer/ubsan/ubsan_handlers.h
+++ b/libsanitizer/ubsan/ubsan_handlers.h
@@ -220,12 +220,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<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 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 0eb109f37d44..47d83718ba21 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 c7eb1a967e53..679fad0ea4c7 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

Reply via email to