From 91d212a4a6c2c87a6e09bc8a5e665b011022aaaf Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Jan 06 2017 20:13:44 +0000 Subject: Vendor import of compiler-rt trunk r291274: https://llvm.org/svn/llvm-project/compiler-rt/trunk@291274 --- diff --git a/cmake/Modules/AddCompilerRT.cmake b/cmake/Modules/AddCompilerRT.cmake index 42ae7ad..c2863d5 100644 --- a/cmake/Modules/AddCompilerRT.cmake +++ b/cmake/Modules/AddCompilerRT.cmake @@ -256,6 +256,7 @@ set(COMPILER_RT_GTEST_CFLAGS ) append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_UNITTEST_CFLAGS) +append_list_if(COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG -Wno-covered-switch-default COMPILER_RT_UNITTEST_CFLAGS) if(MSVC) # clang doesn't support exceptions on Windows yet. diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index 5e2eefc..c6bb850 100644 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -29,7 +29,6 @@ check_cxx_compiler_flag(-std=c++11 COMPILER_RT_HAS_STD_CXX11_FLAG) check_cxx_compiler_flag(-ftls-model=initial-exec COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC) check_cxx_compiler_flag(-fno-lto COMPILER_RT_HAS_FNO_LTO_FLAG) check_cxx_compiler_flag("-Werror -msse3" COMPILER_RT_HAS_MSSE3_FLAG) -check_cxx_compiler_flag("-Werror -msse4.2" COMPILER_RT_HAS_MSSE4_2_FLAG) check_cxx_compiler_flag(--sysroot=. COMPILER_RT_HAS_SYSROOT_FLAG) if(NOT WIN32 AND NOT CYGWIN) @@ -57,6 +56,7 @@ check_cxx_compiler_flag("-Werror -Wgnu" COMPILER_RT_HAS_WGNU_FLAG check_cxx_compiler_flag("-Werror -Wnon-virtual-dtor" COMPILER_RT_HAS_WNON_VIRTUAL_DTOR_FLAG) check_cxx_compiler_flag("-Werror -Wvariadic-macros" COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG) check_cxx_compiler_flag("-Werror -Wunused-parameter" COMPILER_RT_HAS_WUNUSED_PARAMETER_FLAG) +check_cxx_compiler_flag("-Werror -Wcovered-switch-default" COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG) check_cxx_compiler_flag(/W4 COMPILER_RT_HAS_W4_FLAG) check_cxx_compiler_flag(/WX COMPILER_RT_HAS_WX_FLAG) diff --git a/lib/asan/asan_allocator.cc b/lib/asan/asan_allocator.cc index 36bd046..2cf9d08 100644 --- a/lib/asan/asan_allocator.cc +++ b/lib/asan/asan_allocator.cc @@ -681,6 +681,7 @@ struct Allocator { void PrintStats() { allocator.PrintStats(); + quarantine.PrintStats(); } void ForceLock() { @@ -700,18 +701,21 @@ static AsanAllocator &get_allocator() { return instance.allocator; } -bool AsanChunkView::IsValid() { +bool AsanChunkView::IsValid() const { return chunk_ && chunk_->chunk_state != CHUNK_AVAILABLE; } -bool AsanChunkView::IsAllocated() { +bool AsanChunkView::IsAllocated() const { return chunk_ && chunk_->chunk_state == CHUNK_ALLOCATED; } -uptr AsanChunkView::Beg() { return chunk_->Beg(); } -uptr AsanChunkView::End() { return Beg() + UsedSize(); } -uptr AsanChunkView::UsedSize() { return chunk_->UsedSize(); } -uptr AsanChunkView::AllocTid() { return chunk_->alloc_tid; } -uptr AsanChunkView::FreeTid() { return chunk_->free_tid; } -AllocType AsanChunkView::GetAllocType() { +bool AsanChunkView::IsQuarantined() const { + return chunk_ && chunk_->chunk_state == CHUNK_QUARANTINE; +} +uptr AsanChunkView::Beg() const { return chunk_->Beg(); } +uptr AsanChunkView::End() const { return Beg() + UsedSize(); } +uptr AsanChunkView::UsedSize() const { return chunk_->UsedSize(); } +uptr AsanChunkView::AllocTid() const { return chunk_->alloc_tid; } +uptr AsanChunkView::FreeTid() const { return chunk_->free_tid; } +AllocType AsanChunkView::GetAllocType() const { return (AllocType)chunk_->alloc_type; } @@ -722,14 +726,14 @@ static StackTrace GetStackTraceFromId(u32 id) { return res; } -u32 AsanChunkView::GetAllocStackId() { return chunk_->alloc_context_id; } -u32 AsanChunkView::GetFreeStackId() { return chunk_->free_context_id; } +u32 AsanChunkView::GetAllocStackId() const { return chunk_->alloc_context_id; } +u32 AsanChunkView::GetFreeStackId() const { return chunk_->free_context_id; } -StackTrace AsanChunkView::GetAllocStack() { +StackTrace AsanChunkView::GetAllocStack() const { return GetStackTraceFromId(GetAllocStackId()); } -StackTrace AsanChunkView::GetFreeStack() { +StackTrace AsanChunkView::GetFreeStack() const { return GetStackTraceFromId(GetFreeStackId()); } diff --git a/lib/asan/asan_allocator.h b/lib/asan/asan_allocator.h index 51de678..ee28ecf 100644 --- a/lib/asan/asan_allocator.h +++ b/lib/asan/asan_allocator.h @@ -51,28 +51,29 @@ void GetAllocatorOptions(AllocatorOptions *options); class AsanChunkView { public: explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {} - bool IsValid(); // Checks if AsanChunkView points to a valid allocated - // or quarantined chunk. - bool IsAllocated(); // Checks if the memory is currently allocated. - uptr Beg(); // First byte of user memory. - uptr End(); // Last byte of user memory. - uptr UsedSize(); // Size requested by the user. - uptr AllocTid(); - uptr FreeTid(); + bool IsValid() const; // Checks if AsanChunkView points to a valid + // allocated or quarantined chunk. + bool IsAllocated() const; // Checks if the memory is currently allocated. + bool IsQuarantined() const; // Checks if the memory is currently quarantined. + uptr Beg() const; // First byte of user memory. + uptr End() const; // Last byte of user memory. + uptr UsedSize() const; // Size requested by the user. + uptr AllocTid() const; + uptr FreeTid() const; bool Eq(const AsanChunkView &c) const { return chunk_ == c.chunk_; } - u32 GetAllocStackId(); - u32 GetFreeStackId(); - StackTrace GetAllocStack(); - StackTrace GetFreeStack(); - AllocType GetAllocType(); - bool AddrIsInside(uptr addr, uptr access_size, sptr *offset) { + u32 GetAllocStackId() const; + u32 GetFreeStackId() const; + StackTrace GetAllocStack() const; + StackTrace GetFreeStack() const; + AllocType GetAllocType() const; + bool AddrIsInside(uptr addr, uptr access_size, sptr *offset) const { if (addr >= Beg() && (addr + access_size) <= End()) { *offset = addr - Beg(); return true; } return false; } - bool AddrIsAtLeft(uptr addr, uptr access_size, sptr *offset) { + bool AddrIsAtLeft(uptr addr, uptr access_size, sptr *offset) const { (void)access_size; if (addr < Beg()) { *offset = Beg() - addr; @@ -80,7 +81,7 @@ class AsanChunkView { } return false; } - bool AddrIsAtRight(uptr addr, uptr access_size, sptr *offset) { + bool AddrIsAtRight(uptr addr, uptr access_size, sptr *offset) const { if (addr + access_size > End()) { *offset = addr - End(); return true; diff --git a/lib/asan/asan_memory_profile.cc b/lib/asan/asan_memory_profile.cc index c55264e..c2678b9 100644 --- a/lib/asan/asan_memory_profile.cc +++ b/lib/asan/asan_memory_profile.cc @@ -32,18 +32,20 @@ struct AllocationSite { class HeapProfile { public: HeapProfile() : allocations_(1024) {} - void Insert(u32 id, uptr size) { - total_allocated_ += size; - total_count_++; - // Linear lookup will be good enough for most cases (although not all). - for (uptr i = 0; i < allocations_.size(); i++) { - if (allocations_[i].id == id) { - allocations_[i].total_size += size; - allocations_[i].count++; - return; - } + + void ProcessChunk(const AsanChunkView& cv) { + if (cv.IsAllocated()) { + total_allocated_user_size_ += cv.UsedSize(); + total_allocated_count_++; + u32 id = cv.GetAllocStackId(); + if (id) + Insert(id, cv.UsedSize()); + } else if (cv.IsQuarantined()) { + total_quarantined_user_size_ += cv.UsedSize(); + total_quarantined_count_++; + } else { + total_other_count_++; } - allocations_.push_back({id, size, 1}); } void Print(uptr top_percent) { @@ -51,34 +53,50 @@ class HeapProfile { [](const AllocationSite &a, const AllocationSite &b) { return a.total_size > b.total_size; }); - CHECK(total_allocated_); + CHECK(total_allocated_user_size_); uptr total_shown = 0; - Printf("Live Heap Allocations: %zd bytes from %zd allocations; " - "showing top %zd%%\n", total_allocated_, total_count_, top_percent); + Printf("Live Heap Allocations: %zd bytes in %zd chunks; quarantined: " + "%zd bytes in %zd chunks; %zd other chunks; total chunks: %zd; " + "showing top %zd%%\n", + total_allocated_user_size_, total_allocated_count_, + total_quarantined_user_size_, total_quarantined_count_, + total_other_count_, total_allocated_count_ + + total_quarantined_count_ + total_other_count_, top_percent); for (uptr i = 0; i < allocations_.size(); i++) { auto &a = allocations_[i]; Printf("%zd byte(s) (%zd%%) in %zd allocation(s)\n", a.total_size, - a.total_size * 100 / total_allocated_, a.count); + a.total_size * 100 / total_allocated_user_size_, a.count); StackDepotGet(a.id).Print(); total_shown += a.total_size; - if (total_shown * 100 / total_allocated_ > top_percent) + if (total_shown * 100 / total_allocated_user_size_ > top_percent) break; } } private: - uptr total_allocated_ = 0; - uptr total_count_ = 0; + uptr total_allocated_user_size_ = 0; + uptr total_allocated_count_ = 0; + uptr total_quarantined_user_size_ = 0; + uptr total_quarantined_count_ = 0; + uptr total_other_count_ = 0; InternalMmapVector allocations_; + + void Insert(u32 id, uptr size) { + // Linear lookup will be good enough for most cases (although not all). + for (uptr i = 0; i < allocations_.size(); i++) { + if (allocations_[i].id == id) { + allocations_[i].total_size += size; + allocations_[i].count++; + return; + } + } + allocations_.push_back({id, size, 1}); + } }; static void ChunkCallback(uptr chunk, void *arg) { - HeapProfile *hp = reinterpret_cast(arg); - AsanChunkView cv = FindHeapChunkByAllocBeg(chunk); - if (!cv.IsAllocated()) return; - u32 id = cv.GetAllocStackId(); - if (!id) return; - hp->Insert(id, cv.UsedSize()); + reinterpret_cast(arg)->ProcessChunk( + FindHeapChunkByAllocBeg(chunk)); } static void MemoryProfileCB(const SuspendedThreadsList &suspended_threads_list, diff --git a/lib/asan/tests/asan_interface_test.cc b/lib/asan/tests/asan_interface_test.cc index fd43f17..e4e9524 100644 --- a/lib/asan/tests/asan_interface_test.cc +++ b/lib/asan/tests/asan_interface_test.cc @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// #include "asan_test_utils.h" +#include "sanitizer_common/sanitizer_internal_defs.h" #include #include @@ -399,7 +400,7 @@ static void ErrorReportCallbackOneToZ(const char *report) { TEST(AddressSanitizerInterface, SetErrorReportCallbackTest) { __asan_set_error_report_callback(ErrorReportCallbackOneToZ); - EXPECT_DEATH(__asan_report_error(0, 0, 0, 0, true, 1), + EXPECT_DEATH(__asan_report_error((void *)GET_CALLER_PC(), 0, 0, 0, true, 1), ASAN_PCRE_DOTALL "ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF"); __asan_set_error_report_callback(NULL); } diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt index b33786a..3cf7861 100644 --- a/lib/builtins/CMakeLists.txt +++ b/lib/builtins/CMakeLists.txt @@ -415,8 +415,10 @@ set(aarch64_SOURCES fixunstfti.c floatditf.c floatsitf.c + floattitf.c floatunditf.c floatunsitf.c + floatuntitf.c multc3.c trunctfdf2.c trunctfsf2.c diff --git a/lib/builtins/floattitf.c b/lib/builtins/floattitf.c new file mode 100644 index 0000000..994fded --- /dev/null +++ b/lib/builtins/floattitf.c @@ -0,0 +1,82 @@ +//===-- lib/floattitf.c - int128 -> quad-precision conversion -----*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements ti_int to quad-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +#define QUAD_PRECISION +#include "fp_lib.h" +#include "int_lib.h" + +/* Returns: convert a ti_int to a fp_t, rounding toward even. */ + +/* Assumption: fp_t is a IEEE 128 bit floating point type + * ti_int is a 128 bit integral type + */ + +/* seee eeee eeee eeee mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | + * mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +COMPILER_RT_ABI fp_t +__floattitf(ti_int a) { + if (a == 0) + return 0.0; + const unsigned N = sizeof(ti_int) * CHAR_BIT; + const ti_int s = a >> (N-1); + a = (a ^ s) - s; + int sd = N - __clzti2(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > LDBL_MANT_DIG) { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit LDBL_MANT_DIG-1 bits to the right of 1 + * Q = bit LDBL_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) { + case LDBL_MANT_DIG + 1: + a <<= 1; + break; + case LDBL_MANT_DIG + 2: + break; + default: + a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) | + ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */ + if (a & ((tu_int)1 << LDBL_MANT_DIG)) { + a >>= 1; + ++e; + } + /* a is now rounded to LDBL_MANT_DIG bits */ + } else { + a <<= (LDBL_MANT_DIG - sd); + /* a is now rounded to LDBL_MANT_DIG bits */ + } + + long_double_bits fb; + fb.u.high.all = (s & 0x8000000000000000LL) /* sign */ + | (du_int)(e + 16383) << 48 /* exponent */ + | ((a >> 64) & 0x0000ffffffffffffLL); /* significand */ + fb.u.low.all = (du_int)(a); + return fb.f; +} + +#endif diff --git a/lib/builtins/floatuntitf.c b/lib/builtins/floatuntitf.c new file mode 100644 index 0000000..e2518c9 --- /dev/null +++ b/lib/builtins/floatuntitf.c @@ -0,0 +1,79 @@ +//===-- lib/floatuntitf.c - uint128 -> quad-precision conversion --*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements tu_int to quad-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +#define QUAD_PRECISION +#include "fp_lib.h" +#include "int_lib.h" + +/* Returns: convert a tu_int to a fp_t, rounding toward even. */ + +/* Assumption: fp_t is a IEEE 128 bit floating point type + * tu_int is a 128 bit integral type + */ + +/* seee eeee eeee eeee mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | + * mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +COMPILER_RT_ABI fp_t +__floatuntitf(tu_int a) { + if (a == 0) + return 0.0; + const unsigned N = sizeof(tu_int) * CHAR_BIT; + int sd = N - __clzti2(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > LDBL_MANT_DIG) { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit LDBL_MANT_DIG-1 bits to the right of 1 + * Q = bit LDBL_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) { + case LDBL_MANT_DIG + 1: + a <<= 1; + break; + case LDBL_MANT_DIG + 2: + break; + default: + a = (a >> (sd - (LDBL_MANT_DIG+2))) | + ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */ + if (a & ((tu_int)1 << LDBL_MANT_DIG)) { + a >>= 1; + ++e; + } + /* a is now rounded to LDBL_MANT_DIG bits */ + } else { + a <<= (LDBL_MANT_DIG - sd); + /* a is now rounded to LDBL_MANT_DIG bits */ + } + + long_double_bits fb; + fb.u.high.all = (du_int)(e + 16383) << 48 /* exponent */ + | ((a >> 64) & 0x0000ffffffffffffLL); /* significand */ + fb.u.low.all = (du_int)(a); + return fb.f; +} + +#endif diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt index 0d9a7f0..c70b8be 100644 --- a/lib/sanitizer_common/CMakeLists.txt +++ b/lib/sanitizer_common/CMakeLists.txt @@ -52,6 +52,7 @@ set(SANITIZER_NOLIBC_SOURCES set(SANITIZER_LIBCDEP_SOURCES sanitizer_common_libcdep.cc + sancov_flags.cc sanitizer_coverage_libcdep.cc sanitizer_coverage_libcdep_new.cc sanitizer_coverage_mapping_libcdep.cc diff --git a/lib/sanitizer_common/sancov_flags.cc b/lib/sanitizer_common/sancov_flags.cc new file mode 100644 index 0000000..08fd2a4 --- /dev/null +++ b/lib/sanitizer_common/sancov_flags.cc @@ -0,0 +1,60 @@ +//===-- sancov_flags.cc -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Sanitizer Coverage runtime flags. +// +//===----------------------------------------------------------------------===// + +#include "sancov_flags.h" +#include "sanitizer_flag_parser.h" +#include "sanitizer_platform.h" + +#if !SANITIZER_LINUX +// other platforms do not have weak symbols out of the box. +extern "C" const char* __sancov_default_options() { return ""; } +#endif + +using namespace __sanitizer; + +namespace __sancov { + +SancovFlags sancov_flags_dont_use_directly; // use via flags(); + +void SancovFlags::SetDefaults() { +#define SANCOV_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; +#include "sancov_flags.inc" +#undef SANCOV_FLAG +} + +static void RegisterSancovFlags(FlagParser *parser, SancovFlags *f) { +#define SANCOV_FLAG(Type, Name, DefaultValue, Description) \ + RegisterFlag(parser, #Name, Description, &f->Name); +#include "sancov_flags.inc" +#undef SANCOV_FLAG +} + +static const char *MaybeCallSancovDefaultOptions() { + return (&__sancov_default_options) ? __sancov_default_options() : ""; +} + +void InitializeSancovFlags() { + SancovFlags *f = sancov_flags(); + f->SetDefaults(); + + FlagParser parser; + RegisterSancovFlags(&parser, f); + + parser.ParseString(MaybeCallSancovDefaultOptions()); + parser.ParseString(GetEnv("SANCOV_OPTIONS")); + + ReportUnrecognizedFlags(); + if (f->help) parser.PrintFlagDescriptions(); +} + +} // namespace __sancov diff --git a/lib/sanitizer_common/sancov_flags.h b/lib/sanitizer_common/sancov_flags.h new file mode 100644 index 0000000..5fbd7ad --- /dev/null +++ b/lib/sanitizer_common/sancov_flags.h @@ -0,0 +1,40 @@ +//===-- sancov_flags.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Sanitizer Coverage runtime flags. +// +//===----------------------------------------------------------------------===// +#ifndef SANCOV_FLAGS_H +#define SANCOV_FLAGS_H + +#include "sanitizer_flag_parser.h" +#include "sanitizer_internal_defs.h" + +namespace __sancov { + +struct SancovFlags { +#define SANCOV_FLAG(Type, Name, DefaultValue, Description) Type Name; +#include "sancov_flags.inc" +#undef SANCOV_FLAG + + void SetDefaults(); +}; + +extern SancovFlags sancov_flags_dont_use_directly; + +inline SancovFlags* sancov_flags() { return &sancov_flags_dont_use_directly; } + +void InitializeSancovFlags(); + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE const char* +__sancov_default_options(); + +} // namespace __sancov + +#endif diff --git a/lib/sanitizer_common/sancov_flags.inc b/lib/sanitizer_common/sancov_flags.inc new file mode 100644 index 0000000..63a1f0c --- /dev/null +++ b/lib/sanitizer_common/sancov_flags.inc @@ -0,0 +1,21 @@ +//===-- sancov_flags.inc ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Sanitizer Coverage runtime flags. +// +//===----------------------------------------------------------------------===// +#ifndef SANCOV_FLAG +#error "Defnine SANCOV_FLAG prior to including this file!" +#endif + +SANCOV_FLAG(bool, symbolize, true, + "If set, converage information will be symbolized by sancov tool " + "after dumping.") + +SANCOV_FLAG(bool, help, false, "Print flags help.") diff --git a/lib/sanitizer_common/sanitizer_allocator_primary64.h b/lib/sanitizer_common/sanitizer_allocator_primary64.h index f2d94a0..035d92b 100644 --- a/lib/sanitizer_common/sanitizer_allocator_primary64.h +++ b/lib/sanitizer_common/sanitizer_allocator_primary64.h @@ -227,9 +227,8 @@ class SizeClassAllocator64 { uptr in_use = region->n_allocated - region->n_freed; uptr avail_chunks = region->allocated_user / ClassIdToSize(class_id); Printf( - " %02zd (%zd): mapped: %zdK allocs: %zd frees: %zd inuse: %zd " - "num_freed_chunks %zd" - " avail: %zd rss: %zdK releases: %zd\n", + " %02zd (%6zd): mapped: %6zdK allocs: %7zd frees: %7zd inuse: %6zd " + "num_freed_chunks %7zd avail: %6zd rss: %6zdK releases: %6zd\n", class_id, ClassIdToSize(class_id), region->mapped_user >> 10, region->n_allocated, region->n_freed, in_use, region->num_freed_chunks, avail_chunks, rss >> 10, diff --git a/lib/sanitizer_common/sanitizer_common.cc b/lib/sanitizer_common/sanitizer_common.cc index 1c6fc3e..89c5c45 100644 --- a/lib/sanitizer_common/sanitizer_common.cc +++ b/lib/sanitizer_common/sanitizer_common.cc @@ -260,10 +260,12 @@ void LoadedModule::set(const char *module_name, uptr base_address) { } void LoadedModule::set(const char *module_name, uptr base_address, - ModuleArch arch, u8 uuid[kModuleUUIDSize]) { + ModuleArch arch, u8 uuid[kModuleUUIDSize], + bool instrumented) { set(module_name, base_address); arch_ = arch; internal_memcpy(uuid_, uuid, sizeof(uuid_)); + instrumented_ = instrumented; } void LoadedModule::clear() { @@ -271,6 +273,7 @@ void LoadedModule::clear() { full_name_ = nullptr; arch_ = kModuleArchUnknown; internal_memset(uuid_, 0, kModuleUUIDSize); + instrumented_ = false; while (!ranges_.empty()) { AddressRange *r = ranges_.front(); ranges_.pop_front(); diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h index 66c2d26..fee642f 100644 --- a/lib/sanitizer_common/sanitizer_common.h +++ b/lib/sanitizer_common/sanitizer_common.h @@ -672,13 +672,16 @@ const uptr kModuleUUIDSize = 16; class LoadedModule { public: LoadedModule() - : full_name_(nullptr), base_address_(0), arch_(kModuleArchUnknown) { + : full_name_(nullptr), + base_address_(0), + arch_(kModuleArchUnknown), + instrumented_(false) { internal_memset(uuid_, 0, kModuleUUIDSize); ranges_.clear(); } void set(const char *module_name, uptr base_address); void set(const char *module_name, uptr base_address, ModuleArch arch, - u8 uuid[kModuleUUIDSize]); + u8 uuid[kModuleUUIDSize], bool instrumented); void clear(); void addAddressRange(uptr beg, uptr end, bool executable); bool containsAddress(uptr address) const; @@ -687,6 +690,7 @@ class LoadedModule { uptr base_address() const { return base_address_; } ModuleArch arch() const { return arch_; } const u8 *uuid() const { return uuid_; } + bool instrumented() const { return instrumented_; } struct AddressRange { AddressRange *next; @@ -705,6 +709,7 @@ class LoadedModule { uptr base_address_; ModuleArch arch_; u8 uuid_[kModuleUUIDSize]; + bool instrumented_; IntrusiveList ranges_; }; diff --git a/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc b/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc index d83b779..df6d10f 100644 --- a/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc +++ b/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// // Sanitizer Coverage Controller for Trace PC Guard. +#include "sancov_flags.h" #include "sanitizer_allocator_internal.h" #include "sanitizer_atomic.h" #include "sanitizer_common.h" @@ -17,6 +18,7 @@ using namespace __sanitizer; using AddressRange = LoadedModule::AddressRange; +namespace __sancov { namespace { static const u64 Magic64 = 0xC0BFFFFFFFFFFF64ULL; @@ -96,6 +98,10 @@ static void SanitizerDumpCoverage(const uptr* unsorted_pcs, uptr len) { InternalFree(file_path); InternalFree(module_name); InternalFree(pcs); + + if (sancov_flags()->symbolize) { + Printf("TODO(aizatsky): call sancov to symbolize\n"); + } } // Collects trace-pc guard coverage. @@ -106,6 +112,8 @@ class TracePcGuardController { CHECK(!initialized); initialized = true; + InitializeSancovFlags(); + pc_vector.Initialize(0); } @@ -140,26 +148,27 @@ class TracePcGuardController { static TracePcGuardController pc_guard_controller; } // namespace +} // namespace __sancov extern "C" { SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_coverage( // NOLINT const uptr* pcs, uptr len) { - return SanitizerDumpCoverage(pcs, len); + return __sancov::SanitizerDumpCoverage(pcs, len); } SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void __sanitizer_cov_trace_pc_guard(u32* guard) { if (!*guard) return; - pc_guard_controller.TracePcGuard(guard, GET_CALLER_PC() - 1); + __sancov::pc_guard_controller.TracePcGuard(guard, GET_CALLER_PC() - 1); } SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void __sanitizer_cov_trace_pc_guard_init(u32* start, u32* end) { if (start == end || *start) return; - pc_guard_controller.InitTracePcGuard(start, end); + __sancov::pc_guard_controller.InitTracePcGuard(start, end); } SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_trace_pc_guard_coverage() { - pc_guard_controller.Dump(); + __sancov::pc_guard_controller.Dump(); } } // extern "C" diff --git a/lib/sanitizer_common/sanitizer_internal_defs.h b/lib/sanitizer_common/sanitizer_internal_defs.h index 02a1e52..8ebe91a 100644 --- a/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/lib/sanitizer_common/sanitizer_internal_defs.h @@ -289,8 +289,8 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond, enum LinkerInitialized { LINKER_INITIALIZED = 0 }; #if !defined(_MSC_VER) || defined(__clang__) -# define GET_CALLER_PC() (uptr)__builtin_return_address(0) -# define GET_CURRENT_FRAME() (uptr)__builtin_frame_address(0) +#define GET_CALLER_PC() (__sanitizer::uptr) __builtin_return_address(0) +#define GET_CURRENT_FRAME() (__sanitizer::uptr) __builtin_frame_address(0) inline void Trap() { __builtin_trap(); } @@ -299,9 +299,10 @@ extern "C" void* _ReturnAddress(void); extern "C" void* _AddressOfReturnAddress(void); # pragma intrinsic(_ReturnAddress) # pragma intrinsic(_AddressOfReturnAddress) -# define GET_CALLER_PC() (uptr)_ReturnAddress() +#define GET_CALLER_PC() (__sanitizer::uptr) _ReturnAddress() // CaptureStackBackTrace doesn't need to know BP on Windows. -# define GET_CURRENT_FRAME() (((uptr)_AddressOfReturnAddress()) + sizeof(uptr)) +#define GET_CURRENT_FRAME() \ + (((__sanitizer::uptr)_AddressOfReturnAddress()) + sizeof(__sanitizer::uptr)) extern "C" void __ud2(void); # pragma intrinsic(__ud2) @@ -319,11 +320,11 @@ inline void Trap() { } // Forces the compiler to generate a frame pointer in the function. -#define ENABLE_FRAME_POINTER \ - do { \ - volatile uptr enable_fp; \ - enable_fp = GET_CURRENT_FRAME(); \ - (void)enable_fp; \ +#define ENABLE_FRAME_POINTER \ + do { \ + volatile __sanitizer::uptr enable_fp; \ + enable_fp = GET_CURRENT_FRAME(); \ + (void)enable_fp; \ } while (0) } // namespace __sanitizer diff --git a/lib/sanitizer_common/sanitizer_procmaps.h b/lib/sanitizer_common/sanitizer_procmaps.h index 5c26fb7..9dbb5ef 100644 --- a/lib/sanitizer_common/sanitizer_procmaps.h +++ b/lib/sanitizer_common/sanitizer_procmaps.h @@ -77,6 +77,7 @@ class MemoryMappingLayout { u8 current_uuid_[kModuleUUIDSize]; int current_load_cmd_count_; char *current_load_cmd_addr_; + bool current_instrumented_; # endif }; diff --git a/lib/sanitizer_common/sanitizer_procmaps_mac.cc b/lib/sanitizer_common/sanitizer_procmaps_mac.cc index 0dc299c..2831f28 100644 --- a/lib/sanitizer_common/sanitizer_procmaps_mac.cc +++ b/lib/sanitizer_common/sanitizer_procmaps_mac.cc @@ -150,20 +150,34 @@ ModuleArch ModuleArchFromCpuType(cpu_type_t cputype, cpu_subtype_t cpusubtype) { } } +static const load_command *NextCommand(const load_command *lc) { + return (const load_command *)((char *)lc + lc->cmdsize); +} + static void FindUUID(const load_command *first_lc, u8 *uuid_output) { - const load_command *current_lc = first_lc; - while (1) { - if (current_lc->cmd == 0) return; - if (current_lc->cmd == LC_UUID) { - const uuid_command *uuid_lc = (const uuid_command *)current_lc; - const uint8_t *uuid = &uuid_lc->uuid[0]; - internal_memcpy(uuid_output, uuid, kModuleUUIDSize); - return; - } + for (const load_command *lc = first_lc; lc->cmd != 0; lc = NextCommand(lc)) { + if (lc->cmd != LC_UUID) continue; + + const uuid_command *uuid_lc = (const uuid_command *)lc; + const uint8_t *uuid = &uuid_lc->uuid[0]; + internal_memcpy(uuid_output, uuid, kModuleUUIDSize); + return; + } +} + +static bool IsModuleInstrumented(const load_command *first_lc) { + for (const load_command *lc = first_lc; lc->cmd != 0; lc = NextCommand(lc)) { + if (lc->cmd != LC_LOAD_DYLIB) continue; - current_lc = - (const load_command *)(((char *)current_lc) + current_lc->cmdsize); + const dylib_command *dylib_lc = (const dylib_command *)lc; + uint32_t dylib_name_offset = dylib_lc->dylib.name.offset; + const char *dylib_name = ((const char *)dylib_lc) + dylib_name_offset; + dylib_name = StripModuleName(dylib_name); + if (dylib_name != 0 && (internal_strstr(dylib_name, "libclang_rt."))) { + return true; + } } + return false; } bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, @@ -193,10 +207,11 @@ bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, continue; } } + FindUUID((const load_command *)current_load_cmd_addr_, ¤t_uuid_[0]); + current_instrumented_ = + IsModuleInstrumented((const load_command *)current_load_cmd_addr_); } - FindUUID((const load_command *)current_load_cmd_addr_, ¤t_uuid_[0]); - for (; current_load_cmd_count_ >= 0; current_load_cmd_count_--) { switch (current_magic_) { // current_magic_ may be only one of MH_MAGIC, MH_MAGIC_64. @@ -244,7 +259,8 @@ void MemoryMappingLayout::DumpListOfModules( } else { modules->push_back(LoadedModule()); cur_module = &modules->back(); - cur_module->set(cur_name, cur_beg, cur_arch, cur_uuid); + cur_module->set(cur_name, cur_beg, cur_arch, cur_uuid, + current_instrumented_); } cur_module->addAddressRange(cur_beg, cur_end, prot & kProtectionExecute); } diff --git a/lib/sanitizer_common/sanitizer_quarantine.h b/lib/sanitizer_common/sanitizer_quarantine.h index ff8f3fa..3d74ef2 100644 --- a/lib/sanitizer_common/sanitizer_quarantine.h +++ b/lib/sanitizer_common/sanitizer_quarantine.h @@ -73,6 +73,11 @@ class Quarantine { Recycle(cb); } + void PrintStats() const { + // It assumes that the world is stopped, just as the allocator's PrintStats. + cache_.PrintStats(); + } + private: // Read-only data. char pad0_[kCacheLineSize]; @@ -163,8 +168,25 @@ class QuarantineCache { return b; } + void PrintStats() const { + uptr batch_count = 0; + uptr total_quarantine_bytes = 0; + uptr total_quarantine_chunks = 0; + for (List::ConstIterator it = list_.begin(); it != list_.end(); ++it) { + batch_count++; + total_quarantine_bytes += (*it).size; + total_quarantine_chunks += (*it).count; + } + Printf("Global quarantine stats: batches: %zd; bytes: %zd; chunks: %zd " + "(capacity: %zd chunks)\n", + batch_count, total_quarantine_bytes, total_quarantine_chunks, + batch_count * QuarantineBatch::kSize); + } + private: - IntrusiveList list_; + typedef IntrusiveList List; + + List list_; atomic_uintptr_t size_; void SizeAdd(uptr add) { diff --git a/lib/sanitizer_common/sanitizer_stacktrace.cc b/lib/sanitizer_common/sanitizer_stacktrace.cc index 7ad1f1f..2741dde 100644 --- a/lib/sanitizer_common/sanitizer_stacktrace.cc +++ b/lib/sanitizer_common/sanitizer_stacktrace.cc @@ -106,10 +106,6 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, } } -static bool MatchPc(uptr cur_pc, uptr trace_pc, uptr threshold) { - return cur_pc - trace_pc <= threshold || trace_pc - cur_pc <= threshold; -} - void BufferedStackTrace::PopStackFrames(uptr count) { CHECK_LT(count, size); size -= count; @@ -118,15 +114,14 @@ void BufferedStackTrace::PopStackFrames(uptr count) { } } +static uptr Distance(uptr a, uptr b) { return a < b ? b - a : a - b; } + uptr BufferedStackTrace::LocatePcInTrace(uptr pc) { - // Use threshold to find PC in stack trace, as PC we want to unwind from may - // slightly differ from return address in the actual unwinded stack trace. - const int kPcThreshold = 350; - for (uptr i = 0; i < size; ++i) { - if (MatchPc(pc, trace[i], kPcThreshold)) - return i; + uptr best = 0; + for (uptr i = 1; i < size; ++i) { + if (Distance(trace[i], pc) < Distance(trace[best], pc)) best = i; } - return 0; + return best; } } // namespace __sanitizer diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc index c4a57f0..6efd330 100644 --- a/lib/sanitizer_common/sanitizer_win.cc +++ b/lib/sanitizer_common/sanitizer_win.cc @@ -31,6 +31,21 @@ #include "sanitizer_stacktrace.h" #include "sanitizer_symbolizer.h" +// A macro to tell the compiler that this part of the code cannot be reached, +// if the compiler supports this feature. Since we're using this in +// code that is called when terminating the process, the expansion of the +// macro should not terminate the process to avoid infinite recursion. +#if defined(__clang__) +# define BUILTIN_UNREACHABLE() __builtin_unreachable() +#elif defined(__GNUC__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +# define BUILTIN_UNREACHABLE() __builtin_unreachable() +#elif defined(_MSC_VER) +# define BUILTIN_UNREACHABLE() __assume(0) +#else +# define BUILTIN_UNREACHABLE() +#endif + namespace __sanitizer { #include "sanitizer_syscall_generic.inc" @@ -659,7 +674,7 @@ void internal__exit(int exitcode) { if (::IsDebuggerPresent()) __debugbreak(); TerminateProcess(GetCurrentProcess(), exitcode); - __assume(0); + BUILTIN_UNREACHABLE(); } uptr internal_ftruncate(fd_t fd, uptr size) { diff --git a/lib/scudo/CMakeLists.txt b/lib/scudo/CMakeLists.txt index 332c3a9..e683379 100644 --- a/lib/scudo/CMakeLists.txt +++ b/lib/scudo/CMakeLists.txt @@ -4,7 +4,6 @@ include_directories(..) set(SCUDO_CFLAGS ${SANITIZER_COMMON_CFLAGS}) append_rtti_flag(OFF SCUDO_CFLAGS) -append_list_if(COMPILER_RT_HAS_MSSE4_2_FLAG -msse4.2 SCUDO_CFLAGS) set(SCUDO_SOURCES scudo_allocator.cpp diff --git a/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cc index 4ede388..6ffffae 100644 --- a/lib/ubsan/ubsan_handlers.cc +++ b/lib/ubsan/ubsan_handlers.cc @@ -45,10 +45,11 @@ static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer, ReportOptions Opts) { Location Loc = Data->Loc.acquire(); + uptr Alignment = (uptr)1 << Data->LogAlignment; ErrorType ET; if (!Pointer) ET = ErrorType::NullPointerUse; - else if (Data->Alignment && (Pointer & (Data->Alignment - 1))) + else if (Pointer & (Alignment - 1)) ET = ErrorType::MisalignedPointerUse; else ET = ErrorType::InsufficientObjectSize; @@ -74,8 +75,8 @@ static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer, case ErrorType::MisalignedPointerUse: Diag(Loc, DL_Error, "%0 misaligned address %1 for type %3, " "which requires %2 byte alignment") - << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer - << Data->Alignment << Data->Type; + << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer << Alignment + << Data->Type; break; case ErrorType::InsufficientObjectSize: Diag(Loc, DL_Error, "%0 address %1 with insufficient space " @@ -90,13 +91,13 @@ static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer, Diag(Pointer, DL_Note, "pointer points here"); } -void __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data, - ValueHandle Pointer) { +void __ubsan::__ubsan_handle_type_mismatch_v1(TypeMismatchData *Data, + ValueHandle Pointer) { GET_REPORT_OPTIONS(false); handleTypeMismatchImpl(Data, Pointer, Opts); } -void __ubsan::__ubsan_handle_type_mismatch_abort(TypeMismatchData *Data, - ValueHandle Pointer) { +void __ubsan::__ubsan_handle_type_mismatch_v1_abort(TypeMismatchData *Data, + ValueHandle Pointer) { GET_REPORT_OPTIONS(true); handleTypeMismatchImpl(Data, Pointer, Opts); Die(); diff --git a/lib/ubsan/ubsan_handlers.h b/lib/ubsan/ubsan_handlers.h index e0cfd5b..350eb91 100644 --- a/lib/ubsan/ubsan_handlers.h +++ b/lib/ubsan/ubsan_handlers.h @@ -20,7 +20,7 @@ namespace __ubsan { struct TypeMismatchData { SourceLocation Loc; const TypeDescriptor &Type; - uptr Alignment; + unsigned char LogAlignment; unsigned char TypeCheckKind; }; @@ -37,7 +37,7 @@ struct TypeMismatchData { /// \brief Handle a runtime type check failure, caused by either a misaligned /// pointer, a null pointer, or a pointer to insufficient storage for the /// type. -RECOVERABLE(type_mismatch, TypeMismatchData *Data, ValueHandle Pointer) +RECOVERABLE(type_mismatch_v1, TypeMismatchData *Data, ValueHandle Pointer) struct OverflowData { SourceLocation Loc; diff --git a/test/builtins/Unit/floattitf_test.c b/test/builtins/Unit/floattitf_test.c new file mode 100644 index 0000000..928b2e8 --- /dev/null +++ b/test/builtins/Unit/floattitf_test.c @@ -0,0 +1,213 @@ +//===-- floattitf.c - Test __floattitf ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __floattitf for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#define QUAD_PRECISION +#include "fp_lib.h" +#include "int_lib.h" +#include +#include + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) + +/* Returns: convert a ti_int to a fp_t, rounding toward even. */ + +/* Assumption: fp_t is a IEEE 128 bit floating point type + * ti_int is a 128 bit integral type + */ + +/* seee eeee eeee eeee mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | + * mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +COMPILER_RT_ABI fp_t __floattitf(ti_int a); + +int test__floattitf(ti_int a, fp_t expected) { + fp_t x = __floattitf(a); + if (x != expected) { + twords at; + at.all = a; + printf("error in __floattitf(0x%.16llX%.16llX) = %LA, expected %LA\n", + at.s.high, at.s.low, x, expected); + } + return x != expected; +} + +char assumption_1[sizeof(ti_int) == 2*sizeof(di_int)] = {0}; +char assumption_2[sizeof(ti_int)*CHAR_BIT == 128] = {0}; +char assumption_3[sizeof(fp_t)*CHAR_BIT == 128] = {0}; + +#endif + +int main() { +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) + if (test__floattitf(0, 0.0)) + return 1; + + if (test__floattitf(1, 1.0)) + return 1; + if (test__floattitf(2, 2.0)) + return 1; + if (test__floattitf(20, 20.0)) + return 1; + if (test__floattitf(-1, -1.0)) + return 1; + if (test__floattitf(-2, -2.0)) + return 1; + if (test__floattitf(-20, -20.0)) + return 1; + + if (test__floattitf(0x7FFFFF8000000000LL, 0x1.FFFFFEp+62)) + return 1; + if (test__floattitf(0x7FFFFFFFFFFFF800LL, 0x1.FFFFFFFFFFFFEp+62)) + return 1; + if (test__floattitf(0x7FFFFF0000000000LL, 0x1.FFFFFCp+62)) + return 1; + if (test__floattitf(0x7FFFFFFFFFFFF000LL, 0x1.FFFFFFFFFFFFCp+62)) + return 1; + + if (test__floattitf(make_ti(0x8000008000000000LL, 0), -0x1.FFFFFEp+126)) + return 1; + if (test__floattitf(make_ti(0x8000000000000800LL, 0), -0x1.FFFFFFFFFFFFEp+126)) + return 1; + if (test__floattitf(make_ti(0x8000010000000000LL, 0), -0x1.FFFFFCp+126)) + return 1; + if (test__floattitf(make_ti(0x8000000000001000LL, 0), -0x1.FFFFFFFFFFFFCp+126)) + return 1; + + if (test__floattitf(make_ti(0x8000000000000000LL, 0), -0x1.000000p+127)) + return 1; + if (test__floattitf(make_ti(0x8000000000000001LL, 0), -0x1.FFFFFFFFFFFFFFFCp+126L)) + return 1; + + if (test__floattitf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50)) + return 1; + + if (test__floattitf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50)) + return 1; + if (test__floattitf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50)) + return 1; + if (test__floattitf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50)) + return 1; + if (test__floattitf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50)) + return 1; + if (test__floattitf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50)) + return 1; + + if (test__floattitf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50)) + return 1; + if (test__floattitf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50)) + return 1; + if (test__floattitf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50)) + return 1; + if (test__floattitf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50)) + return 1; + if (test__floattitf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50)) + return 1; + + if (test__floattitf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57)) + return 1; + if (test__floattitf(0x023479FD0E092DA1LL, 0x1.1A3CFE870496D08p+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DB0LL, 0x1.1A3CFE870496D8p+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DB8LL, 0x1.1A3CFE870496DCp+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DB6LL, 0x1.1A3CFE870496DBp+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DBFLL, 0x1.1A3CFE870496DF8p+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DC1LL, 0x1.1A3CFE870496E08p+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DC7LL, 0x1.1A3CFE870496E38p+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DC8LL, 0x1.1A3CFE870496E4p+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DCFLL, 0x1.1A3CFE870496E78p+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DD0LL, 0x1.1A3CFE870496E8p+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DD1LL, 0x1.1A3CFE870496E88p+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DD8LL, 0x1.1A3CFE870496ECp+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DDFLL, 0x1.1A3CFE870496EF8p+57L)) + return 1; + if (test__floattitf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57)) + return 1; + + if (test__floattitf(make_ti(0x023479FD0E092DC0LL, 0), 0x1.1A3CFE870496Ep+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DA1LL, 1), 0x1.1A3CFE870496D08p+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DB0LL, 2), 0x1.1A3CFE870496D8p+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DB8LL, 3), 0x1.1A3CFE870496DCp+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DB6LL, 4), 0x1.1A3CFE870496DBp+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DBFLL, 5), 0x1.1A3CFE870496DF8p+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DC1LL, 6), 0x1.1A3CFE870496E08p+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DC7LL, 7), 0x1.1A3CFE870496E38p+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DC8LL, 8), 0x1.1A3CFE870496E4p+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DCFLL, 9), 0x1.1A3CFE870496E78p+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DD0LL, 0), 0x1.1A3CFE870496E8p+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DD1LL, 11), 0x1.1A3CFE870496E88p+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DD8LL, 12), 0x1.1A3CFE870496ECp+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DDFLL, 13), 0x1.1A3CFE870496EF8p+121L)) + return 1; + if (test__floattitf(make_ti(0x023479FD0E092DE0LL, 14), 0x1.1A3CFE870496Fp+121L)) + return 1; + + if (test__floattitf(make_ti(0, 0xFFFFFFFFFFFFFFFFLL), 0x1.FFFFFFFFFFFFFFFEp+63L)) + return 1; + + if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC2801LL), + 0x1.23456789ABCDEF0123456789ABC3p+124L)) + return 1; + if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC3000LL), + 0x1.23456789ABCDEF0123456789ABC3p+124L)) + return 1; + if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC37FFLL), + 0x1.23456789ABCDEF0123456789ABC3p+124L)) + return 1; + if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC3800LL), + 0x1.23456789ABCDEF0123456789ABC4p+124L)) + return 1; + if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC4000LL), + 0x1.23456789ABCDEF0123456789ABC4p+124L)) + return 1; + if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC47FFLL), + 0x1.23456789ABCDEF0123456789ABC4p+124L)) + return 1; + if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC4800LL), + 0x1.23456789ABCDEF0123456789ABC4p+124L)) + return 1; + if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC4801LL), + 0x1.23456789ABCDEF0123456789ABC5p+124L)) + return 1; + if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC57FFLL), + 0x1.23456789ABCDEF0123456789ABC5p+124L)) + return 1; +#else + printf("skipped\n"); +#endif + return 0; +} diff --git a/test/builtins/Unit/floatuntitf_test.c b/test/builtins/Unit/floatuntitf_test.c new file mode 100644 index 0000000..495adcf --- /dev/null +++ b/test/builtins/Unit/floatuntitf_test.c @@ -0,0 +1,220 @@ +//===-- floatuntitf.c - Test __floatuntitf --------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __floatuntitf for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#define QUAD_PRECISION +#include "fp_lib.h" +#include "int_lib.h" +#include +#include + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) + +/* Returns: convert a tu_int to a fp_t, rounding toward even. */ + +/* Assumption: fp_t is a IEEE 128 bit floating point type + * tu_int is a 128 bit integral type + */ + +/* seee eeee eeee eeee mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | + * mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +COMPILER_RT_ABI fp_t __floatuntitf(tu_int a); + +int test__floatuntitf(tu_int a, fp_t expected) { + fp_t x = __floatuntitf(a); + if (x != expected) { + utwords at; + at.all = a; + printf("error in __floatuntitf(0x%.16llX%.16llX) = %LA, expected %LA\n", + at.s.high, at.s.low, x, expected); + } + return x != expected; +} + +char assumption_1[sizeof(tu_int) == 2*sizeof(du_int)] = {0}; +char assumption_2[sizeof(tu_int)*CHAR_BIT == 128] = {0}; +char assumption_3[sizeof(fp_t)*CHAR_BIT == 128] = {0}; + +#endif + +int main() { +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) + if (test__floatuntitf(0, 0.0)) + return 1; + + if (test__floatuntitf(1, 1.0)) + return 1; + if (test__floatuntitf(2, 2.0)) + return 1; + if (test__floatuntitf(20, 20.0)) + return 1; + + if (test__floatuntitf(0x7FFFFF8000000000ULL, 0x1.FFFFFEp+62)) + return 1; + if (test__floatuntitf(0x7FFFFFFFFFFFF800ULL, 0x1.FFFFFFFFFFFFEp+62)) + return 1; + if (test__floatuntitf(0x7FFFFF0000000000ULL, 0x1.FFFFFCp+62)) + return 1; + if (test__floatuntitf(0x7FFFFFFFFFFFF000ULL, 0x1.FFFFFFFFFFFFCp+62)) + return 1; + if (test__floatuntitf(0x7FFFFFFFFFFFFFFFULL, 0xF.FFFFFFFFFFFFFFEp+59L)) + return 1; + if (test__floatuntitf(0xFFFFFFFFFFFFFFFEULL, 0xF.FFFFFFFFFFFFFFEp+60L)) + return 1; + if (test__floatuntitf(0xFFFFFFFFFFFFFFFFULL, 0xF.FFFFFFFFFFFFFFFp+60L)) + return 1; + + if (test__floatuntitf(0x8000008000000000ULL, 0x8.000008p+60)) + return 1; + if (test__floatuntitf(0x8000000000000800ULL, 0x8.0000000000008p+60)) + return 1; + if (test__floatuntitf(0x8000010000000000ULL, 0x8.00001p+60)) + return 1; + if (test__floatuntitf(0x8000000000001000ULL, 0x8.000000000001p+60)) + return 1; + + if (test__floatuntitf(0x8000000000000000ULL, 0x8p+60)) + return 1; + if (test__floatuntitf(0x8000000000000001ULL, 0x8.000000000000001p+60L)) + return 1; + + if (test__floatuntitf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50)) + return 1; + + if (test__floatuntitf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50)) + return 1; + if (test__floatuntitf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50)) + return 1; + if (test__floatuntitf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50)) + return 1; + if (test__floatuntitf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50)) + return 1; + if (test__floatuntitf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50)) + return 1; + + if (test__floatuntitf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50)) + return 1; + if (test__floatuntitf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50)) + return 1; + if (test__floatuntitf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50)) + return 1; + if (test__floatuntitf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50)) + return 1; + if (test__floatuntitf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50)) + return 1; + + if (test__floatuntitf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57)) + return 1; + if (test__floatuntitf(0x023479FD0E092DA1LL, 0x1.1A3CFE870496D08p+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DB0LL, 0x1.1A3CFE870496D8p+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DB8LL, 0x1.1A3CFE870496DCp+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DB6LL, 0x1.1A3CFE870496DBp+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DBFLL, 0x1.1A3CFE870496DF8p+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DC1LL, 0x1.1A3CFE870496E08p+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DC7LL, 0x1.1A3CFE870496E38p+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DC8LL, 0x1.1A3CFE870496E4p+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DCFLL, 0x1.1A3CFE870496E78p+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DD0LL, 0x1.1A3CFE870496E8p+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DD1LL, 0x1.1A3CFE870496E88p+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DD8LL, 0x1.1A3CFE870496ECp+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DDFLL, 0x1.1A3CFE870496EF8p+57L)) + return 1; + if (test__floatuntitf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57)) + return 1; + + if (test__floatuntitf(make_ti(0x023479FD0E092DC0LL, 0), 0x1.1A3CFE870496Ep+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DA1LL, 1), 0x1.1A3CFE870496D08p+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DB0LL, 2), 0x1.1A3CFE870496D8p+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DB8LL, 3), 0x1.1A3CFE870496DCp+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DB6LL, 4), 0x1.1A3CFE870496DBp+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DBFLL, 5), 0x1.1A3CFE870496DF8p+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DC1LL, 6), 0x1.1A3CFE870496E08p+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DC7LL, 7), 0x1.1A3CFE870496E38p+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DC8LL, 8), 0x1.1A3CFE870496E4p+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DCFLL, 9), 0x1.1A3CFE870496E78p+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DD0LL, 0), 0x1.1A3CFE870496E8p+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DD1LL, 11), 0x1.1A3CFE870496E88p+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DD8LL, 12), 0x1.1A3CFE870496ECp+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DDFLL, 13), 0x1.1A3CFE870496EF8p+121L)) + return 1; + if (test__floatuntitf(make_ti(0x023479FD0E092DE0LL, 14), 0x1.1A3CFE870496Fp+121L)) + return 1; + + if (test__floatuntitf(make_ti(0, 0xFFFFFFFFFFFFFFFFLL), 0x1.FFFFFFFFFFFFFFFEp+63L)) + return 1; + + if (test__floatuntitf(make_ti(0xFFFFFFFFFFFFFFFFLL, 0x0000000000000000LL), + 0x1.FFFFFFFFFFFFFFFEp+127L)) + return 1; + if (test__floatuntitf(make_ti(0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFLL), + 0x1.0000000000000000p+128L)) + return 1; + + if (test__floatuntitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC2801LL), + 0x1.23456789ABCDEF0123456789ABC3p+124L)) + return 1; + if (test__floatuntitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC3000LL), + 0x1.23456789ABCDEF0123456789ABC3p+124L)) + return 1; + if (test__floatuntitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC37FFLL), + 0x1.23456789ABCDEF0123456789ABC3p+124L)) + return 1; + if (test__floatuntitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC3800LL), + 0x1.23456789ABCDEF0123456789ABC4p+124L)) + return 1; + if (test__floatuntitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC4000LL), + 0x1.23456789ABCDEF0123456789ABC4p+124L)) + return 1; + if (test__floatuntitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC47FFLL), + 0x1.23456789ABCDEF0123456789ABC4p+124L)) + return 1; + if (test__floatuntitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC4800LL), + 0x1.23456789ABCDEF0123456789ABC4p+124L)) + return 1; + if (test__floatuntitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC4801LL), + 0x1.23456789ABCDEF0123456789ABC5p+124L)) + return 1; + if (test__floatuntitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC57FFLL), + 0x1.23456789ABCDEF0123456789ABC5p+124L)) + return 1; +#else + printf("skipped\n"); +#endif + return 0; +} diff --git a/test/sanitizer_common/TestCases/sanitizer_coverage_symbolize.cc b/test/sanitizer_common/TestCases/sanitizer_coverage_symbolize.cc new file mode 100644 index 0000000..48f32a7 --- /dev/null +++ b/test/sanitizer_common/TestCases/sanitizer_coverage_symbolize.cc @@ -0,0 +1,34 @@ +// Tests trace pc guard coverage collection. +// +// REQUIRES: x86_64-linux +// XFAIL: tsan +// +// RUN: DIR=%t_workdir +// RUN: rm -rf $DIR +// RUN: mkdir -p $DIR +// RUN: cd $DIR +// RUN: %clangxx -O0 -fsanitize-coverage=trace-pc-guard %s -ldl -o %t +// RUN: %env_tool_opts=coverage=1 %t 2>&1 | FileCheck %s +// RUN: %env_tool_opts=coverage=1 SANCOV_OPTIONS=symbolize=0 %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOSYM +// RUN: rm -rf $DIR + +#include + +int foo() { + fprintf(stderr, "foo\n"); + return 1; +} + +int main() { + fprintf(stderr, "main\n"); + foo(); + foo(); +} + +// CHECK: main +// CHECK: SanitizerCoverage: ./sanitizer_coverage_symbolize.{{.*}}.sancov 2 PCs written +// CHECK: call sancov + +// CHECK-NOSYM: main +// CHECK-NOSYM: SanitizerCoverage: ./sanitizer_coverage_symbolize.{{.*}}.sancov 2 PCs written +// CHECK-NOSYM-NOT: call sancov