From 0c7a928859f41bc8ea47d97da5df4aac75bbd5fe Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 5 May 2022 12:52:44 +0200 Subject: libsanitizer: Apply local patches --- .../sanitizer_common/sanitizer_linux_libcdep.cpp | 4 ++ libsanitizer/sanitizer_common/sanitizer_mac.cpp | 12 ++++- libsanitizer/sanitizer_common/sanitizer_mac.h | 20 +++++++ .../sanitizer_platform_limits_linux.cpp | 5 +- .../sanitizer_common/sanitizer_procmaps_mac.cpp | 62 ++++------------------ .../sanitizer_common/sanitizer_stacktrace.cpp | 17 ++++-- 6 files changed, 60 insertions(+), 60 deletions(-) (limited to 'libsanitizer/sanitizer_common') diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp index d74851c..56d2316 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -822,9 +822,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 23c4c66..a2591e9 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 "C" { #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 f0a97d0..1cf2e29 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 bf0f355..c278c87 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 4b0e678..ba4259a 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_stacktrace.cpp b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp index d24fae9..661495e 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) -- cgit v1.1