libsanitizer: merge from upstream

Message ID df41aa83-4958-477b-8c2e-49f6ba381c86@suse.cz
State New
Headers
Series libsanitizer: merge from upstream |

Commit Message

Martin Liška May 4, 2022, 8:59 a.m. UTC
  Hello.

I'm going to do merge from upstream.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests. I've also tested
on ppc64le-linux-gnu and verified the ABI.

The only real change is a small change in
gcc/testsuite/c-c++-common/asan/alloca_loop_unpoisoning.c
where we need --param=asan-use-after-return=0.

I'm going to push the patches.

Thanks,
Martin
  

Comments

H.J. Lu May 4, 2022, 11:07 p.m. UTC | #1
On Wed, May 4, 2022 at 1:59 AM Martin Liška <mliska@suse.cz> wrote:
>
> Hello.
>
> I'm going to do merge from upstream.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. I've also tested
> on ppc64le-linux-gnu and verified the ABI.
>
> The only real change is a small change in
> gcc/testsuite/c-c++-common/asan/alloca_loop_unpoisoning.c
> where we need --param=asan-use-after-return=0.
>
> I'm going to push the patches.

Hi,

I am checking in this patch to cherry-pick

f52e365092aa [sanitizer] Use newfstatat for x32

to restore x32 build.
  
Martin Liška May 5, 2022, 11:24 a.m. UTC | #2
On 5/5/22 01:07, H.J. Lu wrote:
> On Wed, May 4, 2022 at 1:59 AM Martin Liška <mliska@suse.cz> wrote:
>> 
>> Hello.
>> 
>> I'm going to do merge from upstream.
>> 
>> Patch can bootstrap on x86_64-linux-gnu and survives regression
>> tests. I've also tested on ppc64le-linux-gnu and verified the ABI.
>> 
>> The only real change is a small change in 
>> gcc/testsuite/c-c++-common/asan/alloca_loop_unpoisoning.c where we
>> need --param=asan-use-after-return=0.
>> 
>> I'm going to push the patches.
> 
> Hi,
> 
> I am checking in this patch to cherry-pick
> 
> f52e365092aa [sanitizer] Use newfstatat for x32
> 
> to restore x32 build.
> 

I'm going to do one more merge from upstream
(75f9e83ace52773af65dcebca543005ec8a2705d) as we want to include Tobias's
revision 6f095babc2b7d564168c7afc5bf6afb2188fd6b4 and my
revision f1b9245199f3457a4d06d32d1bc6e44573c166e3.

Martin
  
H.J. Lu May 5, 2022, 4:21 p.m. UTC | #3
On Thu, May 5, 2022 at 4:24 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 5/5/22 01:07, H.J. Lu wrote:
> > On Wed, May 4, 2022 at 1:59 AM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> Hello.
> >>
> >> I'm going to do merge from upstream.
> >>
> >> Patch can bootstrap on x86_64-linux-gnu and survives regression
> >> tests. I've also tested on ppc64le-linux-gnu and verified the ABI.
> >>
> >> The only real change is a small change in
> >> gcc/testsuite/c-c++-common/asan/alloca_loop_unpoisoning.c where we
> >> need --param=asan-use-after-return=0.
> >>
> >> I'm going to push the patches.
> >
> > Hi,
> >
> > I am checking in this patch to cherry-pick
> >
> > f52e365092aa [sanitizer] Use newfstatat for x32
> >
> > to restore x32 build.
> >
>
> I'm going to do one more merge from upstream
> (75f9e83ace52773af65dcebca543005ec8a2705d) as we want to include Tobias's
> revision 6f095babc2b7d564168c7afc5bf6afb2188fd6b4 and my
> revision f1b9245199f3457a4d06d32d1bc6e44573c166e3.

I am testing a patch for

https://github.com/llvm/llvm-project/issues/55288

to fix:

https://gcc.gnu.org/pipermail/gcc-regression/2022-May/076571.html

The same bug is also in GCC 12.  But somehow, it doesn't show up in
GCC tests.
  
Martin Liška May 5, 2022, 6:28 p.m. UTC | #4
On 5/5/22 18:21, H.J. Lu wrote:
> On Thu, May 5, 2022 at 4:24 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 5/5/22 01:07, H.J. Lu wrote:
>>> On Wed, May 4, 2022 at 1:59 AM Martin Liška <mliska@suse.cz> wrote:
>>>>
>>>> Hello.
>>>>
>>>> I'm going to do merge from upstream.
>>>>
>>>> Patch can bootstrap on x86_64-linux-gnu and survives regression
>>>> tests. I've also tested on ppc64le-linux-gnu and verified the ABI.
>>>>
>>>> The only real change is a small change in
>>>> gcc/testsuite/c-c++-common/asan/alloca_loop_unpoisoning.c where we
>>>> need --param=asan-use-after-return=0.
>>>>
>>>> I'm going to push the patches.
>>>
>>> Hi,
>>>
>>> I am checking in this patch to cherry-pick
>>>
>>> f52e365092aa [sanitizer] Use newfstatat for x32
>>>
>>> to restore x32 build.
>>>
>>
>> I'm going to do one more merge from upstream
>> (75f9e83ace52773af65dcebca543005ec8a2705d) as we want to include Tobias's
>> revision 6f095babc2b7d564168c7afc5bf6afb2188fd6b4 and my
>> revision f1b9245199f3457a4d06d32d1bc6e44573c166e3.
> 
> I am testing a patch for
> 
> https://github.com/llvm/llvm-project/issues/55288
> 
> to fix:
> 
> https://gcc.gnu.org/pipermail/gcc-regression/2022-May/076571.html

Interesting. How did you run these tests that the error shows up?

> 
> The same bug is also in GCC 12.  But somehow, it doesn't show up in
> GCC tests.

So please backport it once it's merged.

Martin
  
H.J. Lu May 5, 2022, 6:40 p.m. UTC | #5
On Thu, May 5, 2022 at 11:28 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 5/5/22 18:21, H.J. Lu wrote:
> > On Thu, May 5, 2022 at 4:24 AM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 5/5/22 01:07, H.J. Lu wrote:
> >>> On Wed, May 4, 2022 at 1:59 AM Martin Liška <mliska@suse.cz> wrote:
> >>>>
> >>>> Hello.
> >>>>
> >>>> I'm going to do merge from upstream.
> >>>>
> >>>> Patch can bootstrap on x86_64-linux-gnu and survives regression
> >>>> tests. I've also tested on ppc64le-linux-gnu and verified the ABI.
> >>>>
> >>>> The only real change is a small change in
> >>>> gcc/testsuite/c-c++-common/asan/alloca_loop_unpoisoning.c where we
> >>>> need --param=asan-use-after-return=0.
> >>>>
> >>>> I'm going to push the patches.
> >>>
> >>> Hi,
> >>>
> >>> I am checking in this patch to cherry-pick
> >>>
> >>> f52e365092aa [sanitizer] Use newfstatat for x32
> >>>
> >>> to restore x32 build.
> >>>
> >>
> >> I'm going to do one more merge from upstream
> >> (75f9e83ace52773af65dcebca543005ec8a2705d) as we want to include Tobias's
> >> revision 6f095babc2b7d564168c7afc5bf6afb2188fd6b4 and my
> >> revision f1b9245199f3457a4d06d32d1bc6e44573c166e3.
> >
> > I am testing a patch for
> >
> > https://github.com/llvm/llvm-project/issues/55288

I submitted:

https://reviews.llvm.org/D125025

> > to fix:
> >
> > https://gcc.gnu.org/pipermail/gcc-regression/2022-May/076571.html
>
> Interesting. How did you run these tests that the error shows up?

Just normal GCC bootstrap and check with x32 enabled.

> >
> > The same bug is also in GCC 12.  But somehow, it doesn't show up in
> > GCC tests.
>
> So please backport it once it's merged.
>

Will do after GCC 12 is released.

Thanks.
  
Martin Liška Aug. 30, 2022, 10:53 a.m. UTC | #6
On 5/4/22 10:59, Martin Liška wrote:
> Hello.
> 
> I'm going to do merge from upstream.
> 
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. I've also tested
> on ppc64le-linux-gnu and verified the ABI.
> 
> The only real change is a small change in
> gcc/testsuite/c-c++-common/asan/alloca_loop_unpoisoning.c
> where we need --param=asan-use-after-return=0.
> 
> I'm going to push the patches.
> 
> Thanks,
> Martin

Hi.

I've just done one more merge from upstream.
Upstream revision: 84a71d5259c2682403cdbd8710592410a2f128ab.

Cheers,
Martin
  
Iain Sandoe Sept. 4, 2022, 7:50 p.m. UTC | #7
Hi Martin,

> On 30 Aug 2022, at 11:53, Martin Liška <mliska@suse.cz> wrote:
> 
> On 5/4/22 10:59, Martin Liška wrote:
>> Hello.
> I've just done one more merge from upstream.
> Upstream revision: 84a71d5259c2682403cdbd8710592410a2f128ab.

Which (again) breaks bootstrap on Darwin (since upstream uses features
and APIs not present in GCC and/or supported by the systems we support).

Worked around as below; we will need to find a way to handle the
macOS 13+ changes.

Iain


[pushed] [libsanitizer, Darwin] Fix bootstrap after recent merge.

The latest merge to libsanitizer includes changes to handle macOS 13+.
However, these changes are incompatible with GCC and so we need to find
an alternate solution.  To restore bootstrap back this change out until
the alternate can be found.
---
 .../sanitizer_procmaps_mac.cpp                | 62 +++----------------
 1 file changed, 10 insertions(+), 52 deletions(-)

diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
index 4b0e6781976..ba4259acd46 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();
     }
  
Martin Liška Sept. 5, 2022, 7:31 a.m. UTC | #8
On 9/4/22 21:50, Iain Sandoe wrote:
> Hi Martin,
> 
>> On 30 Aug 2022, at 11:53, Martin Liška <mliska@suse.cz> wrote:
>>
>> On 5/4/22 10:59, Martin Liška wrote:
>>> Hello.
>> I've just done one more merge from upstream.
>> Upstream revision: 84a71d5259c2682403cdbd8710592410a2f128ab.
> 
> Which (again) breaks bootstrap on Darwin (since upstream uses features
> and APIs not present in GCC and/or supported by the systems we support).

Hi.

Can you please report that to upstream and create a patch that would
be accepted by upstream?

Thanks,
Martin

> 
> Worked around as below; we will need to find a way to handle the
> macOS 13+ changes.
> 
> Iain
> 
> 
> [pushed] [libsanitizer, Darwin] Fix bootstrap after recent merge.
> 
> The latest merge to libsanitizer includes changes to handle macOS 13+.
> However, these changes are incompatible with GCC and so we need to find
> an alternate solution.  To restore bootstrap back this change out until
> the alternate can be found.
> ---
>  .../sanitizer_procmaps_mac.cpp                | 62 +++----------------
>  1 file changed, 10 insertions(+), 52 deletions(-)
> 
> diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
> index 4b0e6781976..ba4259acd46 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();
>      }
  
Rainer Orth Sept. 5, 2022, 7:44 a.m. UTC | #9
Hi Martin,

> On 9/4/22 21:50, Iain Sandoe wrote:
>> Hi Martin,
>> 
>>> On 30 Aug 2022, at 11:53, Martin Liška <mliska@suse.cz> wrote:
>>>
>>> On 5/4/22 10:59, Martin Liška wrote:
>>>> Hello.
>>> I've just done one more merge from upstream.
>>> Upstream revision: 84a71d5259c2682403cdbd8710592410a2f128ab.
>> 
>> Which (again) breaks bootstrap on Darwin (since upstream uses features
>> and APIs not present in GCC and/or supported by the systems we support).
>
> Hi.
>
> Can you please report that to upstream and create a patch that would
> be accepted by upstream?

this may be difficult, unfortunately.  Some time ago, I tried to get an
answer to the question which macOS versions are supposed to be supported
by upstream LLVM and got nothing, despite the massive involvement of
Apple in the project.  Still, it's certainly worth a try.

As a datapoint, both recent libsanitizer imports broke Solaris 11.3
bootstrap, which is still supported by GCC, but never was by LLVM.  In
the first case, I managed to get a patch in to fix that (and a
non-trivial one at that), in the current case I even created the
breakage myself by (again) forgetting that upstream eventually gets
imported into GCC with its wider range of supported Solaris versions.

	Rainer
  

Patch

From 1c0069ab7ad0d76072adf3dc006b515a670a3ccb Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 20 Jul 2021 10:46:51 -0700
Subject: [PATCH 2/4] libsanitizer: Apply local patches

---
 libsanitizer/asan/asan_globals.cpp            | 19 ------------------
 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_platform_limits_posix.h         |  2 +-
 .../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_platform.h           |  2 ++
 14 files changed, 85 insertions(+), 30 deletions(-)

diff --git a/libsanitizer/asan/asan_globals.cpp b/libsanitizer/asan/asan_globals.cpp
index ecc2600f039..326a49798f0 100644
--- a/libsanitizer/asan/asan_globals.cpp
+++ b/libsanitizer/asan/asan_globals.cpp
@@ -153,23 +153,6 @@  static void CheckODRViolationViaIndicator(const Global *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) {
-  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 (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
-      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
@@ -215,8 +198,6 @@  static void RegisterGlobal(const Global *g) {
     // 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 047b044c8bf..105c672cc24 100644
--- a/libsanitizer/asan/asan_interceptors.h
+++ b/libsanitizer/asan/asan_interceptors.h
@@ -81,7 +81,12 @@  void InitializePlatformInterceptors();
 #if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && !SANITIZER_SOLARIS && \
     !SANITIZER_NETBSD
 # 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 4ff09b103d5..1b6669e1270 100644
--- a/libsanitizer/asan/asan_mapping.h
+++ b/libsanitizer/asan/asan_mapping.h
@@ -181,7 +181,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 25ad825f568..d966d857a76 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -792,9 +792,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 05512a576ad..7ce8d670ecc 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(<os/trace.h>)
+#if defined(__has_include) && __has_include(<os/trace.h>) && defined(__BLOCKS__)
 #define SANITIZER_OS_TRACE 1
 #include <os/trace.h>
 #else
@@ -71,7 +71,15 @@  extern "C" {
 #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 <sched.h>
 #include <signal.h>
diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_mac.h
index 0b6af5a3c0e..96a5986a47a 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_MAC
 #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 9d577570ea1..2b1a2f7932c 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_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
index 62a99035db3..89772a7e5c0 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -83,7 +83,7 @@  const unsigned struct_kernel_stat64_sz = 104;
 #elif defined(__mips__)
 const unsigned struct_kernel_stat_sz = SANITIZER_ANDROID
                                            ? FIRST_32_SECOND_64(104, 128)
-                                           : FIRST_32_SECOND_64(160, 216);
+                                           : FIRST_32_SECOND_64(144, 216);
 const unsigned struct_kernel_stat64_sz = 104;
 #elif defined(__s390__) && !defined(__s390x__)
 const unsigned struct_kernel_stat_sz = 64;
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp
index 3013a0c4abd..7386285f34b 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(__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 e201e6bba22..2184625aa6e 100644
--- a/libsanitizer/ubsan/ubsan_handlers.cpp
+++ b/libsanitizer/ubsan/ubsan_handlers.cpp
@@ -894,6 +894,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 219fb15de55..9f412353fc0 100644
--- a/libsanitizer/ubsan/ubsan_handlers.h
+++ b/libsanitizer/ubsan/ubsan_handlers.h
@@ -215,12 +215,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_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
-- 
2.36.0