forked from OSchip/llvm-project
				
			[tsan] Fix __cxa_guard_* interceptors on OS X
This patch fixes the __cxa_guard_acquire, __cxa_guard_release and __cxa_guard_abort interceptors on OS X. They apparently work on Linux just by having the same name, but on OS X, we actually need to use TSAN_INTERCEPTOR. Differential Revision: http://reviews.llvm.org/D14868 llvm-svn: 253776
This commit is contained in:
		
							parent
							
								
									5cbe122439
								
							
						
					
					
						commit
						6bbb8519e2
					
				| 
						 | 
					@ -786,8 +786,25 @@ TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// __cxa_guard_acquire and friends need to be intercepted in a special way -
 | 
				
			||||||
 | 
					// regular interceptors will break statically-linked libstdc++. Linux
 | 
				
			||||||
 | 
					// interceptors are especially defined as weak functions (so that they don't
 | 
				
			||||||
 | 
					// cause link errors when user defines them as well). So they silently
 | 
				
			||||||
 | 
					// auto-disable themselves when such symbol is already present in the binary. If
 | 
				
			||||||
 | 
					// we link libstdc++ statically, it will bring own __cxa_guard_acquire which
 | 
				
			||||||
 | 
					// will silently replace our interceptor.  That's why on Linux we simply export
 | 
				
			||||||
 | 
					// these interceptors with INTERFACE_ATTRIBUTE.
 | 
				
			||||||
 | 
					// On OS X, we don't support statically linking, so we just use a regular
 | 
				
			||||||
 | 
					// interceptor.
 | 
				
			||||||
 | 
					#if SANITIZER_MAC
 | 
				
			||||||
 | 
					#define STDCXX_INTERCEPTOR TSAN_INTERCEPTOR
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define STDCXX_INTERCEPTOR(rettype, name, ...) \
 | 
				
			||||||
 | 
					  extern "C" rettype INTERFACE_ATTRIBUTE name(__VA_ARGS__)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Used in thread-safe function static initialization.
 | 
					// Used in thread-safe function static initialization.
 | 
				
			||||||
extern "C" int INTERFACE_ATTRIBUTE __cxa_guard_acquire(atomic_uint32_t *g) {
 | 
					STDCXX_INTERCEPTOR(int, __cxa_guard_acquire, atomic_uint32_t *g) {
 | 
				
			||||||
  SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire, g);
 | 
					  SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire, g);
 | 
				
			||||||
  for (;;) {
 | 
					  for (;;) {
 | 
				
			||||||
    u32 cmp = atomic_load(g, memory_order_acquire);
 | 
					    u32 cmp = atomic_load(g, memory_order_acquire);
 | 
				
			||||||
| 
						 | 
					@ -803,13 +820,13 @@ extern "C" int INTERFACE_ATTRIBUTE __cxa_guard_acquire(atomic_uint32_t *g) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern "C" void INTERFACE_ATTRIBUTE __cxa_guard_release(atomic_uint32_t *g) {
 | 
					STDCXX_INTERCEPTOR(void, __cxa_guard_release, atomic_uint32_t *g) {
 | 
				
			||||||
  SCOPED_INTERCEPTOR_RAW(__cxa_guard_release, g);
 | 
					  SCOPED_INTERCEPTOR_RAW(__cxa_guard_release, g);
 | 
				
			||||||
  Release(thr, pc, (uptr)g);
 | 
					  Release(thr, pc, (uptr)g);
 | 
				
			||||||
  atomic_store(g, 1, memory_order_release);
 | 
					  atomic_store(g, 1, memory_order_release);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern "C" void INTERFACE_ATTRIBUTE __cxa_guard_abort(atomic_uint32_t *g) {
 | 
					STDCXX_INTERCEPTOR(void, __cxa_guard_abort, atomic_uint32_t *g) {
 | 
				
			||||||
  SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort, g);
 | 
					  SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort, g);
 | 
				
			||||||
  atomic_store(g, 0, memory_order_relaxed);
 | 
					  atomic_store(g, 0, memory_order_relaxed);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue