[ubsan-minimal] Get rid of the libc++ dependency.
Summary: Use -nodefaultlibs. Replace std:atomic with sanitizer atomics. Reviewers: vitalybuka, kongyi, EricWF Subscribers: mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D39934 llvm-svn: 317969
This commit is contained in:
		
							parent
							
								
									0eb4a43384
								
							
						
					
					
						commit
						24bc8d5905
					
				| 
						 | 
				
			
			@ -9,8 +9,9 @@ include_directories(..)
 | 
			
		|||
set(UBSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
 | 
			
		||||
append_rtti_flag(OFF UBSAN_CFLAGS)
 | 
			
		||||
 | 
			
		||||
set(UBSAN_STANDALONE_CFLAGS ${SANITIZER_COMMON_CFLAGS})
 | 
			
		||||
append_rtti_flag(OFF UBSAN_STANDALONE_CFLAGS)
 | 
			
		||||
set(UBSAN_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
 | 
			
		||||
 | 
			
		||||
set(UBSAN_DYNAMIC_LIBS ${SANITIZER_COMMON_LINK_LIBS})
 | 
			
		||||
 | 
			
		||||
add_compiler_rt_component(ubsan-minimal)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +40,7 @@ if(COMPILER_RT_HAS_UBSAN_MINIMAL)
 | 
			
		|||
    ARCHS ${UBSAN_SUPPORTED_ARCH}
 | 
			
		||||
    OBJECT_LIBS RTUbsan_minimal
 | 
			
		||||
    CFLAGS ${UBSAN_CFLAGS}
 | 
			
		||||
    LINK_FLAGS ${UBSAN_LINK_FLAGS}
 | 
			
		||||
    LINK_LIBS ${UBSAN_DYNAMIC_LIBS}
 | 
			
		||||
    PARENT_TARGET ubsan-minimal)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
#include <atomic>
 | 
			
		||||
#include "sanitizer_common/sanitizer_atomic.h"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -8,37 +10,38 @@ static void message(const char *msg) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static const int kMaxCallerPcs = 20;
 | 
			
		||||
static std::atomic<void *> caller_pcs[kMaxCallerPcs];
 | 
			
		||||
static __sanitizer::atomic_uintptr_t caller_pcs[kMaxCallerPcs];
 | 
			
		||||
// Number of elements in caller_pcs. A special value of kMaxCallerPcs + 1 means
 | 
			
		||||
// that "too many errors" has already been reported.
 | 
			
		||||
static std::atomic<int> caller_pcs_sz;
 | 
			
		||||
static __sanitizer::atomic_uint32_t caller_pcs_sz;
 | 
			
		||||
 | 
			
		||||
__attribute__((noinline))
 | 
			
		||||
static bool report_this_error(void *caller) {
 | 
			
		||||
  if (caller == nullptr) return false;
 | 
			
		||||
__attribute__((noinline)) static bool report_this_error(void *caller_p) {
 | 
			
		||||
  uintptr_t caller = reinterpret_cast<uintptr_t>(caller_p);
 | 
			
		||||
  if (caller == 0) return false;
 | 
			
		||||
  while (true) {
 | 
			
		||||
    int sz = caller_pcs_sz.load(std::memory_order_relaxed);
 | 
			
		||||
    if (sz > kMaxCallerPcs) return false; // early exit
 | 
			
		||||
    unsigned sz = __sanitizer::atomic_load_relaxed(&caller_pcs_sz);
 | 
			
		||||
    if (sz > kMaxCallerPcs) return false;  // early exit
 | 
			
		||||
    // when sz==kMaxCallerPcs print "too many errors", but only when cmpxchg
 | 
			
		||||
    // succeeds in order to not print it multiple times.
 | 
			
		||||
    if (sz > 0 && sz < kMaxCallerPcs) {
 | 
			
		||||
      void *p;
 | 
			
		||||
      for (int i = 0; i < sz; ++i) {
 | 
			
		||||
        p = caller_pcs[i].load(std::memory_order_relaxed);
 | 
			
		||||
        if (p == nullptr) break; // Concurrent update.
 | 
			
		||||
      uintptr_t p;
 | 
			
		||||
      for (unsigned i = 0; i < sz; ++i) {
 | 
			
		||||
        p = __sanitizer::atomic_load_relaxed(&caller_pcs[i]);
 | 
			
		||||
        if (p == 0) break;  // Concurrent update.
 | 
			
		||||
        if (p == caller) return false;
 | 
			
		||||
      }
 | 
			
		||||
      if (p == nullptr) continue; // FIXME: yield?
 | 
			
		||||
      if (p == 0) continue;  // FIXME: yield?
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!caller_pcs_sz.compare_exchange_strong(sz, sz + 1))
 | 
			
		||||
      continue; // Concurrent update! Try again from the start.
 | 
			
		||||
    if (!__sanitizer::atomic_compare_exchange_strong(
 | 
			
		||||
            &caller_pcs_sz, &sz, sz + 1, __sanitizer::memory_order_seq_cst))
 | 
			
		||||
      continue;  // Concurrent update! Try again from the start.
 | 
			
		||||
 | 
			
		||||
    if (sz == kMaxCallerPcs) {
 | 
			
		||||
      message("ubsan: too many errors\n");
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    caller_pcs[sz].store(caller, std::memory_order_relaxed);
 | 
			
		||||
    __sanitizer::atomic_store_relaxed(&caller_pcs[sz], caller);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue