Index: asan_intercepted_functions.h =================================================================== --- asan_intercepted_functions.h +++ asan_intercepted_functions.h @@ -198,8 +198,6 @@ typedef u64 dispatch_time_t; typedef void (*dispatch_function_t)(void *block); typedef void* (*worker_t)(void *block); -typedef void* CFStringRef; -typedef void* CFAllocatorRef; DECLARE_FUNCTION_AND_WRAPPER(void, dispatch_async_f, dispatch_queue_t dq, @@ -216,11 +214,6 @@ DECLARE_FUNCTION_AND_WRAPPER(void, dispatch_group_async_f, dispatch_group_t group, dispatch_queue_t dq, void *ctxt, dispatch_function_t func); - -DECLARE_FUNCTION_AND_WRAPPER(void, __CFInitialize, void); -DECLARE_FUNCTION_AND_WRAPPER(CFStringRef, CFStringCreateCopy, - CFAllocatorRef alloc, CFStringRef str); -DECLARE_FUNCTION_AND_WRAPPER(void, free, void* ptr); #if MAC_INTERPOSE_FUNCTIONS && !defined(MISSING_BLOCKS_SUPPORT) DECLARE_FUNCTION_AND_WRAPPER(void, dispatch_group_async, dispatch_group_t dg, @@ -234,6 +227,28 @@ DECLARE_FUNCTION_AND_WRAPPER(void, dispatch_source_set_cancel_handler, dispatch_source_t ds, void (^work)(void)); #endif // MAC_INTERPOSE_FUNCTIONS + +typedef void malloc_zone_t; +typedef size_t vm_size_t; +DECLARE_FUNCTION_AND_WRAPPER(malloc_zone_t *, malloc_create_zone, + vm_size_t start_size, unsigned flags); +DECLARE_FUNCTION_AND_WRAPPER(malloc_zone_t *, malloc_default_zone, void); +DECLARE_FUNCTION_AND_WRAPPER(malloc_zone_t *, malloc_default_purgeable_zone, void); +DECLARE_FUNCTION_AND_WRAPPER(void, malloc_make_purgeable, void *ptr); +DECLARE_FUNCTION_AND_WRAPPER(int, malloc_make_nonpurgeable, void *ptr); +DECLARE_FUNCTION_AND_WRAPPER(void, malloc_set_zone_name, malloc_zone_t *zone, const char *name); +DECLARE_FUNCTION_AND_WRAPPER(void *, malloc, size_t size); +DECLARE_FUNCTION_AND_WRAPPER(void, free, void *ptr); +DECLARE_FUNCTION_AND_WRAPPER(void *, realloc, void *ptr, size_t size); +DECLARE_FUNCTION_AND_WRAPPER(void *, calloc, size_t nmemb, size_t size); +DECLARE_FUNCTION_AND_WRAPPER(void *, valloc, size_t size); +DECLARE_FUNCTION_AND_WRAPPER(size_t, malloc_good_size, size_t size); +DECLARE_FUNCTION_AND_WRAPPER(int, posix_memalign, void **memptr, size_t alignment, size_t size); +DECLARE_FUNCTION_AND_WRAPPER(void, _malloc_fork_prepare, void); +DECLARE_FUNCTION_AND_WRAPPER(void, _malloc_fork_parent, void); +DECLARE_FUNCTION_AND_WRAPPER(void, _malloc_fork_child, void); + + #endif // __APPLE__ } // extern "C" #endif Index: asan_mac.cc =================================================================== --- asan_mac.cc +++ asan_mac.cc @@ -36,7 +36,6 @@ #include // for free() #include #include -#include namespace __asan { @@ -131,14 +130,6 @@ } void AsanPlatformThreadInit() { - // For the first program thread, we can't replace the allocator before - // __CFInitialize() has been called. If it hasn't, we'll call - // MaybeReplaceCFAllocator() later on this thread. - // For other threads __CFInitialize() has been called before their creation. - // See also asan_malloc_mac.cc. - if (((CFRuntimeBase*)kCFAllocatorSystemDefault)->_cfisa) { - MaybeReplaceCFAllocator(); - } } AsanLock::AsanLock(LinkerInitialized) { @@ -483,29 +474,6 @@ gencountp); } -// See http://opensource.apple.com/source/CF/CF-635.15/CFString.c -int __CFStrIsConstant(CFStringRef str) { - CFRuntimeBase *base = (CFRuntimeBase*)str; -#if __LP64__ - return base->_rc == 0; -#else - return (base->_cfinfo[CF_RC_BITS]) == 0; -#endif -} - -INTERCEPTOR(CFStringRef, CFStringCreateCopy, CFAllocatorRef alloc, - CFStringRef str) { - if (__CFStrIsConstant(str)) { - return str; - } else { - return REAL(CFStringCreateCopy)(alloc, str); - } -} - -DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr) - -DECLARE_REAL_AND_INTERCEPTOR(void, __CFInitialize, void) - namespace __asan { void InitializeMacInterceptors() { @@ -520,20 +488,6 @@ if (flags()->verbosity >= 2) { CHECK(INTERCEPT_FUNCTION(pthread_workqueue_additem_np)); } - // Normally CFStringCreateCopy should not copy constant CF strings. - // Replacing the default CFAllocator causes constant strings to be copied - // rather than just returned, which leads to bugs in big applications like - // Chromium and WebKit, see - // http://code.google.com/p/address-sanitizer/issues/detail?id=10 - // Until this problem is fixed we need to check that the string is - // non-constant before calling CFStringCreateCopy. - CHECK(INTERCEPT_FUNCTION(CFStringCreateCopy)); - // Some of the library functions call free() directly, so we have to - // intercept it. - CHECK(INTERCEPT_FUNCTION(free)); - if (flags()->replace_cfallocator) { - CHECK(INTERCEPT_FUNCTION(__CFInitialize)); - } } } // namespace __asan Index: asan_malloc_mac.cc =================================================================== --- asan_malloc_mac.cc +++ asan_malloc_mac.cc @@ -38,83 +38,108 @@ static malloc_zone_t *system_malloc_zone = 0; static malloc_zone_t *system_purgeable_zone = 0; static malloc_zone_t asan_zone; -CFAllocatorRef cf_asan = 0; -// _CFRuntimeCreateInstance() checks whether the supplied allocator is -// kCFAllocatorSystemDefault and, if it is not, stores the allocator reference -// at the beginning of the allocated memory and returns the pointer to the -// allocated memory plus sizeof(CFAllocatorRef). See -// http://www.opensource.apple.com/source/CF/CF-635.21/CFRuntime.c -// Pointers returned by _CFRuntimeCreateInstance() can then be passed directly -// to free() or CFAllocatorDeallocate(), which leads to false invalid free -// reports. -// The corresponding rdar bug is http://openradar.appspot.com/radar?id=1796404. -void* ALWAYS_INLINE get_saved_cfallocator_ref(void *ptr) { - if (flags()->replace_cfallocator) { - // Make sure we're not hitting the previous page. This may be incorrect - // if ASan's malloc returns an address ending with 0xFF8, which will be - // then padded to a page boundary with a CFAllocatorRef. - uptr arith_ptr = (uptr)ptr; - if ((arith_ptr & 0xFFF) > sizeof(CFAllocatorRef)) { - CFAllocatorRef *saved = - (CFAllocatorRef*)(arith_ptr - sizeof(CFAllocatorRef)); - if ((*saved == cf_asan) && asan_mz_size(saved)) ptr = (void*)saved; - } +INTERCEPTOR(malloc_zone_t *, malloc_create_zone, + vm_size_t start_size, unsigned zone_flags) { + if (!asan_inited) __asan_init(); + GET_STACK_TRACE_MALLOC; + malloc_zone_t *new_zone = + (malloc_zone_t*)asan_malloc(sizeof(malloc_zone_t), &stack); + internal_memcpy(new_zone, &asan_zone, sizeof(malloc_zone_t)); + new_zone->zone_name = NULL; // The name will be changed anyway. + return new_zone; +} + +INTERCEPTOR(malloc_zone_t *, malloc_default_zone, void) { + if (!asan_inited) __asan_init(); + return &asan_zone; +} + +INTERCEPTOR(malloc_zone_t *, malloc_default_purgeable_zone, void) { + // FIXME: ASan should support purgeable allocations. + // https://code.google.com/p/address-sanitizer/issues/detail?id=139 + if (!asan_inited) __asan_init(); + return &asan_zone; +} + +INTERCEPTOR(void, malloc_make_purgeable, void *ptr) { + // FIXME: ASan should support purgeable allocations. Ignoring them is fine + // for now. + if (!asan_inited) __asan_init(); +} + +INTERCEPTOR(int, malloc_make_nonpurgeable, void *ptr) { + // FIXME: ASan should support purgeable allocations. Ignoring them is fine + // for now. + if (!asan_inited) __asan_init(); + // Must return 0 if the contents were not purged since the last call to + // malloc_make_purgeable(). + return 0; +} + +INTERCEPTOR(void, malloc_set_zone_name, malloc_zone_t *zone, const char *name) { + if (!asan_inited) __asan_init(); + // Allocate |strlen("asan-") + 1 + internal_strlen(name)| bytes. + size_t buflen = 6 + (name ? internal_strlen(name) : 0 ); + InternalScopedBuffer new_name(buflen); + if (name && zone->introspect == asan_zone.introspect) { + internal_snprintf(new_name.data(), buflen, "asan-%s", name); + new_name.data()[buflen - 1] = '\0'; + name = new_name.data(); } - return ptr; + + // Call the system malloc's implementation for both external and our zones, + // since that appropriately changes VM region protections on the zone. + REAL(malloc_set_zone_name)(zone, name); +} + +INTERCEPTOR(void *, malloc, size_t size) { + if (!asan_inited) __asan_init(); + GET_STACK_TRACE_MALLOC; + void *res = asan_malloc(size, &stack); + return res; } -// The free() implementation provided by OS X calls malloc_zone_from_ptr() -// to find the owner of |ptr|. If the result is 0, an invalid free() is -// reported. Our implementation falls back to asan_free() in this case -// in order to print an ASan-style report. -// -// For the objects created by _CFRuntimeCreateInstance a CFAllocatorRef is -// placed at the beginning of the allocated chunk and the pointer returned by -// our allocator is off by sizeof(CFAllocatorRef). This pointer can be then -// passed directly to free(), which will lead to errors. -// To overcome this we're checking whether |ptr-sizeof(CFAllocatorRef)| -// contains a pointer to our CFAllocator (assuming no other allocator is used). -// See http://code.google.com/p/address-sanitizer/issues/detail?id=70 for more -// info. INTERCEPTOR(void, free, void *ptr) { - malloc_zone_t *zone = malloc_zone_from_ptr(ptr); - if (zone) { -#if defined(MAC_OS_X_VERSION_10_6) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - if ((zone->version >= 6) && (zone->free_definite_size)) { - zone->free_definite_size(zone, ptr, malloc_size(ptr)); - } else { - malloc_zone_free(zone, ptr); - } -#else - malloc_zone_free(zone, ptr); -#endif - } else { - if (!asan_mz_size(ptr)) ptr = get_saved_cfallocator_ref(ptr); - GET_STACK_TRACE_FREE; - asan_free(ptr, &stack, FROM_MALLOC); - } + if (!asan_inited) __asan_init(); + if (!ptr) return; + GET_STACK_TRACE_FREE; + asan_free(ptr, &stack, FROM_MALLOC); } -// We can't always replace the default CFAllocator with cf_asan right in -// ReplaceSystemMalloc(), because it is sometimes called before -// __CFInitialize(), when the default allocator is invalid and replacing it may -// crash the program. Instead we wait for the allocator to initialize and jump -// in just after __CFInitialize(). Nobody is going to allocate memory using -// CFAllocators before that, so we won't miss anything. -// -// See http://code.google.com/p/address-sanitizer/issues/detail?id=87 -// and http://opensource.apple.com/source/CF/CF-550.43/CFRuntime.c -INTERCEPTOR(void, __CFInitialize, void) { - // If the runtime is built as dynamic library, __CFInitialize wrapper may be - // called before __asan_init. -#if !MAC_INTERPOSE_FUNCTIONS - CHECK(flags()->replace_cfallocator); - CHECK(asan_inited); -#endif - REAL(__CFInitialize)(); - if (!cf_asan && asan_inited) MaybeReplaceCFAllocator(); +INTERCEPTOR(void *, realloc, void *ptr, size_t size) { + if (!asan_inited) __asan_init(); + GET_STACK_TRACE_MALLOC; + return asan_realloc(ptr, size, &stack); +} + +INTERCEPTOR(void *, calloc, size_t nmemb, size_t size) { + if (!asan_inited) __asan_init(); + GET_STACK_TRACE_MALLOC; + return asan_calloc(nmemb, size, &stack); +} + +INTERCEPTOR(void *, valloc, size_t size) { + if (!asan_inited) __asan_init(); + GET_STACK_TRACE_MALLOC; + return asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC); +} + +INTERCEPTOR(size_t, malloc_good_size, size_t size) { + if (!asan_inited) __asan_init(); + return asan_zone.introspect->good_size(&asan_zone, size); +} + +INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) { + if (!asan_inited) __asan_init(); + CHECK(memptr); + GET_STACK_TRACE_MALLOC; + void *result = asan_memalign(alignment, size, &stack, FROM_MALLOC); + if (result) { + *memptr = result; + return 0; + } + return -1; } namespace { @@ -134,15 +159,6 @@ return asan_malloc(size, &stack); } -void *cf_malloc(CFIndex size, CFOptionFlags hint, void *info) { - if (!asan_inited) { - CHECK(system_malloc_zone); - return malloc_zone_malloc(system_malloc_zone, size); - } - GET_STACK_TRACE_MALLOC; - return asan_malloc(size, &stack); -} - void *mz_calloc(malloc_zone_t *zone, size_t nmemb, size_t size) { if (!asan_inited) { // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. @@ -174,31 +190,14 @@ void ALWAYS_INLINE free_common(void *context, void *ptr) { if (!ptr) return; - if (asan_mz_size(ptr)) { - GET_STACK_TRACE_FREE; + GET_STACK_TRACE_FREE; + // FIXME: need to retire this flag. + if (!flags()->mac_ignore_invalid_free) { asan_free(ptr, &stack, FROM_MALLOC); } else { - // If the pointer does not belong to any of the zones, use one of the - // fallback methods to free memory. - malloc_zone_t *zone_ptr = malloc_zone_from_ptr(ptr); - if (zone_ptr == system_purgeable_zone) { - // allocations from malloc_default_purgeable_zone() done before - // __asan_init() may be occasionally freed via free_common(). - // see http://code.google.com/p/address-sanitizer/issues/detail?id=99. - malloc_zone_free(zone_ptr, ptr); - } else { - // If the memory chunk pointer was moved to store additional - // CFAllocatorRef, fix it back. - ptr = get_saved_cfallocator_ref(ptr); - GET_STACK_TRACE_FREE; - if (!flags()->mac_ignore_invalid_free) { - asan_free(ptr, &stack, FROM_MALLOC); - } else { - GET_ZONE_FOR_PTR(ptr); - WarnMacFreeUnallocated((uptr)ptr, (uptr)zone_ptr, zone_name, &stack); - return; - } - } + GET_ZONE_FOR_PTR(ptr); + WarnMacFreeUnallocated((uptr)ptr, (uptr)zone_ptr, zone_name, &stack); + return; } } @@ -207,10 +206,6 @@ free_common(zone, ptr); } -void cf_free(void *ptr, void *info) { - free_common(info, ptr); -} - void *mz_realloc(malloc_zone_t *zone, void *ptr, size_t size) { if (!ptr) { GET_STACK_TRACE_MALLOC; @@ -230,29 +225,11 @@ } } -void *cf_realloc(void *ptr, CFIndex size, CFOptionFlags hint, void *info) { - if (!ptr) { - GET_STACK_TRACE_MALLOC; - return asan_malloc(size, &stack); - } else { - if (asan_mz_size(ptr)) { - GET_STACK_TRACE_MALLOC; - return asan_realloc(ptr, size, &stack); - } else { - // We can't recover from reallocating an unknown address, because - // this would require reading at most |size| bytes from - // potentially unaccessible memory. - GET_STACK_TRACE_FREE; - GET_ZONE_FOR_PTR(ptr); - ReportMacCfReallocUnknown((uptr)ptr, (uptr)zone_ptr, zone_name, &stack); - } - } -} - void mz_destroy(malloc_zone_t* zone) { // A no-op -- we will not be destroyed! - Printf("mz_destroy() called -- ignoring\n"); + Report("mz_destroy() called -- ignoring\n"); } + // from AvailabilityMacros.h #if defined(MAC_OS_X_VERSION_10_6) && \ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 @@ -324,23 +301,7 @@ } // unnamed namespace -extern int __CFRuntimeClassTableSize; - namespace __asan { -void MaybeReplaceCFAllocator() { - static CFAllocatorContext asan_context = { - /*version*/ 0, /*info*/ &asan_zone, - /*retain*/ 0, /*release*/ 0, - /*copyDescription*/0, - /*allocate*/ &cf_malloc, - /*reallocate*/ &cf_realloc, - /*deallocate*/ &cf_free, - /*preferredSize*/ 0 }; - if (!cf_asan) - cf_asan = CFAllocatorCreate(kCFAllocatorUseContext, &asan_context); - if (flags()->replace_cfallocator && CFAllocatorGetDefault() != cf_asan) - CFAllocatorSetDefault(cf_asan); -} void ReplaceSystemMalloc() { static malloc_introspection_t asan_introspection; @@ -380,41 +341,10 @@ asan_zone.free_definite_size = 0; asan_zone.memalign = &mz_memalign; asan_introspection.zone_locked = &mi_zone_locked; - - // Request the default purgable zone to force its creation. The - // current default zone is registered with the purgable zone for - // doing tiny and small allocs. Sadly, it assumes that the default - // zone is the szone implementation from OS X and will crash if it - // isn't. By creating the zone now, this will be true and changing - // the default zone won't cause a problem. (OS X 10.6 and higher.) - system_purgeable_zone = malloc_default_purgeable_zone(); #endif - // Register the ASan zone. At this point, it will not be the - // default zone. + // Register the ASan zone. malloc_zone_register(&asan_zone); - - // Unregister and reregister the default zone. Unregistering swaps - // the specified zone with the last one registered which for the - // default zone makes the more recently registered zone the default - // zone. The default zone is then re-registered to ensure that - // allocations made from it earlier will be handled correctly. - // Things are not guaranteed to work that way, but it's how they work now. - system_malloc_zone = malloc_default_zone(); - malloc_zone_unregister(system_malloc_zone); - malloc_zone_register(system_malloc_zone); - // Make sure the default allocator was replaced. - CHECK(malloc_default_zone() == &asan_zone); - - // If __CFInitialize() hasn't been called yet, cf_asan will be created and - // installed as the default allocator after __CFInitialize() finishes (see - // the interceptor for __CFInitialize() above). Otherwise install cf_asan - // right now. On both Snow Leopard and Lion __CFInitialize() calls - // __CFAllocatorInitialize(), which initializes the _base._cfisa field of - // the default allocators we check here. - if (((CFRuntimeBase*)kCFAllocatorSystemDefault)->_cfisa) { - MaybeReplaceCFAllocator(); - } } } // namespace __asan Index: dynamic/asan_interceptors_dynamic.cc =================================================================== --- dynamic/asan_interceptors_dynamic.cc +++ dynamic/asan_interceptors_dynamic.cc @@ -101,9 +101,19 @@ INTERPOSE_FUNCTION(signal), INTERPOSE_FUNCTION(sigaction), - INTERPOSE_FUNCTION(__CFInitialize), - INTERPOSE_FUNCTION(CFStringCreateCopy), + INTERPOSE_FUNCTION(malloc_create_zone), + INTERPOSE_FUNCTION(malloc_default_zone), + INTERPOSE_FUNCTION(malloc_default_purgeable_zone), + INTERPOSE_FUNCTION(malloc_make_purgeable), + INTERPOSE_FUNCTION(malloc_make_nonpurgeable), + INTERPOSE_FUNCTION(malloc_set_zone_name), + INTERPOSE_FUNCTION(malloc), INTERPOSE_FUNCTION(free), + INTERPOSE_FUNCTION(realloc), + INTERPOSE_FUNCTION(calloc), + INTERPOSE_FUNCTION(valloc), + INTERPOSE_FUNCTION(malloc_good_size), + INTERPOSE_FUNCTION(posix_memalign), }; } // namespace __asan Index: lit_tests/Darwin/interface_symbols_darwin.c =================================================================== --- lit_tests/Darwin/interface_symbols_darwin.c +++ lit_tests/Darwin/interface_symbols_darwin.c @@ -0,0 +1,37 @@ +// Check the presense of interface symbols in the ASan runtime dylib. +// If you're changing this file, please also change +// ../Linux/interface_symbols.c + +// RUN: %clang -fsanitize=address -dead_strip -O2 %s -o %t.exe +// RUN: rm -f %t.symbols %t.interface + +// RUN: nm `otool -L %t.exe | grep "asan_osx_dynamic.dylib" | \ +// RUN: tr -d '\011' | \ +// RUN: sed "s/.dylib.*/.dylib/"` \ +// RUN: | grep " T " | sed "s/.* T //" \ +// RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" \ +// RUN: | grep -v "__asan_malloc_hook" \ +// RUN: | grep -v "__asan_free_hook" \ +// RUN: | grep -v "__asan_symbolize" \ +// RUN: | grep -v "__asan_default_options" \ +// RUN: | grep -v "__asan_on_error" > %t.symbols + +// RUN: cat %p/../../../../include/sanitizer/asan_interface.h \ +// RUN: | sed "s/\/\/.*//" | sed "s/typedef.*//" \ +// RUN: | grep -v "OPTIONAL" \ +// RUN: | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \ +// RUN: > %t.interface +// RUN: echo __asan_report_load1 >> %t.interface +// RUN: echo __asan_report_load2 >> %t.interface +// RUN: echo __asan_report_load4 >> %t.interface +// RUN: echo __asan_report_load8 >> %t.interface +// RUN: echo __asan_report_load16 >> %t.interface +// RUN: echo __asan_report_store1 >> %t.interface +// RUN: echo __asan_report_store2 >> %t.interface +// RUN: echo __asan_report_store4 >> %t.interface +// RUN: echo __asan_report_store8 >> %t.interface +// RUN: echo __asan_report_store16 >> %t.interface + +// RUN: cat %t.interface | sort -u | diff %t.symbols - + +int main() { return 0; } Index: lit_tests/Darwin/lit.local.cfg =================================================================== --- lit_tests/Darwin/lit.local.cfg +++ lit_tests/Darwin/lit.local.cfg @@ -0,0 +1,9 @@ +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +if root.host_os not in ['Darwin']: + config.unsupported = True Index: lit_tests/Linux/interface_symbols_linux.c =================================================================== --- lit_tests/Linux/interface_symbols_linux.c +++ lit_tests/Linux/interface_symbols_linux.c @@ -1,6 +1,10 @@ // Check the presense of interface symbols in compiled file. +// If you're changing this file, please also change +// ../Darwin/interface_symbols.c // RUN: %clang -fsanitize=address -dead_strip -O2 %s -o %t.exe +// RUN: rm -f %t.symbols %t.interface + // RUN: nm %t.exe | grep " T " | sed "s/.* T //" \ // RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" \ // RUN: | grep -v "__asan_malloc_hook" \ @@ -8,7 +12,8 @@ // RUN: | grep -v "__asan_symbolize" \ // RUN: | grep -v "__asan_default_options" \ // RUN: | grep -v "__asan_on_error" > %t.symbols -// RUN: cat %p/../../../include/sanitizer/asan_interface.h \ + +// RUN: cat %p/../../../../include/sanitizer/asan_interface.h \ // RUN: | sed "s/\/\/.*//" | sed "s/typedef.*//" \ // RUN: | grep -v "OPTIONAL" \ // RUN: | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \ @@ -23,6 +28,7 @@ // RUN: echo __asan_report_store4 >> %t.interface // RUN: echo __asan_report_store8 >> %t.interface // RUN: echo __asan_report_store16 >> %t.interface + // RUN: cat %t.interface | sort -u | diff %t.symbols - int main() { return 0; } Index: lit_tests/heap-overflow.cc =================================================================== --- lit_tests/heap-overflow.cc +++ lit_tests/heap-overflow.cc @@ -29,10 +29,8 @@ // CHECK-Linux: {{ #0 0x.* in .*malloc}} // CHECK-Linux: {{ #1 0x.* in main .*heap-overflow.cc:21}} - // CHECK-Darwin: {{ #0 0x.* in .*mz_malloc.*}} - // CHECK-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}} - // CHECK-Darwin: {{ #2 0x.* in malloc.*}} - // CHECK-Darwin: {{ #3 0x.* in _?main .*heap-overflow.cc:21}} + // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}} + // CHECK-Darwin: {{ #1 0x.* in _?main .*heap-overflow.cc:21}} free(x); return res; } Index: lit_tests/interface_symbols.c =================================================================== --- lit_tests/interface_symbols.c +++ lit_tests/interface_symbols.c @@ -1,28 +0,0 @@ -// Check the presense of interface symbols in compiled file. - -// RUN: %clang -fsanitize=address -dead_strip -O2 %s -o %t.exe -// RUN: nm %t.exe | grep " T " | sed "s/.* T //" \ -// RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" \ -// RUN: | grep -v "__asan_malloc_hook" \ -// RUN: | grep -v "__asan_free_hook" \ -// RUN: | grep -v "__asan_symbolize" \ -// RUN: | grep -v "__asan_default_options" \ -// RUN: | grep -v "__asan_on_error" > %t.symbols -// RUN: cat %p/../../../include/sanitizer/asan_interface.h \ -// RUN: | sed "s/\/\/.*//" | sed "s/typedef.*//" \ -// RUN: | grep -v "OPTIONAL" \ -// RUN: | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \ -// RUN: > %t.interface -// RUN: echo __asan_report_load1 >> %t.interface -// RUN: echo __asan_report_load2 >> %t.interface -// RUN: echo __asan_report_load4 >> %t.interface -// RUN: echo __asan_report_load8 >> %t.interface -// RUN: echo __asan_report_load16 >> %t.interface -// RUN: echo __asan_report_store1 >> %t.interface -// RUN: echo __asan_report_store2 >> %t.interface -// RUN: echo __asan_report_store4 >> %t.interface -// RUN: echo __asan_report_store8 >> %t.interface -// RUN: echo __asan_report_store16 >> %t.interface -// RUN: cat %t.interface | sort -u | diff %t.symbols - - -int main() { return 0; } Index: lit_tests/strncpy-overflow.cc =================================================================== --- lit_tests/strncpy-overflow.cc +++ lit_tests/strncpy-overflow.cc @@ -32,9 +32,7 @@ // CHECK-Linux: {{ #0 0x.* in .*malloc}} // CHECK-Linux: {{ #1 0x.* in main .*strncpy-overflow.cc:}}[[@LINE-10]] - // CHECK-Darwin: {{ #0 0x.* in .*mz_malloc.*}} - // CHECK-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}} - // CHECK-Darwin: {{ #2 0x.* in malloc.*}} - // CHECK-Darwin: {{ #3 0x.* in _?main .*strncpy-overflow.cc:}}[[@LINE-15]] + // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}} + // CHECK-Darwin: {{ #1 0x.* in _?main .*strncpy-overflow.cc:}}[[@LINE-13]] return short_buffer[8]; } Index: lit_tests/use-after-free.cc =================================================================== --- lit_tests/use-after-free.cc +++ lit_tests/use-after-free.cc @@ -30,19 +30,14 @@ // CHECK-Linux: {{ #0 0x.* in .*free}} // CHECK-Linux: {{ #1 0x.* in main .*use-after-free.cc:21}} - // CHECK-Darwin: {{ #0 0x.* in .*free_common.*}} - // CHECK-Darwin: {{ #1 0x.* in .*mz_free.*}} - // We override free() on Darwin, thus no malloc_zone_free - // CHECK-Darwin: {{ #2 0x.* in _?wrap_free}} - // CHECK-Darwin: {{ #3 0x.* in _?main .*use-after-free.cc:21}} + // CHECK-Darwin: {{ #0 0x.* in _?wrap_free}} + // CHECK-Darwin: {{ #1 0x.* in _?main .*use-after-free.cc:21}} // CHECK: {{previously allocated by thread T0 here:}} // CHECK-Linux: {{ #0 0x.* in .*malloc}} // CHECK-Linux: {{ #1 0x.* in main .*use-after-free.cc:20}} - // CHECK-Darwin: {{ #0 0x.* in .*mz_malloc.*}} - // CHECK-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}} - // CHECK-Darwin: {{ #2 0x.* in malloc.*}} - // CHECK-Darwin: {{ #3 0x.* in _?main .*use-after-free.cc:20}} + // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}} + // CHECK-Darwin: {{ #1 0x.* in _?main .*use-after-free.cc:20}} }