diff options
-rw-r--r-- | lib/sanitizer_common/sanitizer_printf.cc | 44 | ||||
-rw-r--r-- | lib/ubsan/CMakeLists.txt | 10 | ||||
-rw-r--r-- | lib/ubsan/ubsan_diag.cc | 57 | ||||
-rw-r--r-- | lib/ubsan/ubsan_handlers.cc | 12 |
4 files changed, 71 insertions, 52 deletions
diff --git a/lib/sanitizer_common/sanitizer_printf.cc b/lib/sanitizer_common/sanitizer_printf.cc index f834d2ba0..938384871 100644 --- a/lib/sanitizer_common/sanitizer_printf.cc +++ b/lib/sanitizer_common/sanitizer_printf.cc @@ -55,13 +55,16 @@ static int AppendUnsigned(char **buff, const char *buff_end, u64 num, return result; } -static int AppendSignedDecimal(char **buff, const char *buff_end, s64 num) { +static int AppendSignedDecimal(char **buff, const char *buff_end, s64 num, + u8 minimal_num_length) { int result = 0; if (num < 0) { result += AppendChar(buff, buff_end, '-'); num = -num; + if (minimal_num_length) + --minimal_num_length; } - result += AppendUnsigned(buff, buff_end, (u64)num, 10, 0); + result += AppendUnsigned(buff, buff_end, (u64)num, 10, minimal_num_length); return result; } @@ -85,8 +88,8 @@ static int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) { int VSNPrintf(char *buff, int buff_length, const char *format, va_list args) { - static const char *kPrintfFormatsHelp = "Supported Printf formats: " - "%%[z]{d,u,x}; %%p; %%s; %%c\n"; + static const char *kPrintfFormatsHelp = + "Supported Printf formats: %%(0[0-9]*)?(z|ll)?{d,u,x}; %%p; %%s; %%c\n"; RAW_CHECK(format); RAW_CHECK(buff_length > 0); const char *buff_end = &buff[buff_length - 1]; @@ -98,42 +101,55 @@ int VSNPrintf(char *buff, int buff_length, continue; } cur++; + bool have_width = (*cur == '0'); + int width = 0; + if (have_width) { + while (*cur >= '0' && *cur <= '9') { + have_width = true; + width = width * 10 + *cur++ - '0'; + } + } bool have_z = (*cur == 'z'); cur += have_z; + bool have_ll = !have_z && (cur[0] == 'l' && cur[1] == 'l'); + cur += have_ll * 2; s64 dval; u64 uval; + bool have_flags = have_width | have_z | have_ll; switch (*cur) { case 'd': { - dval = have_z ? va_arg(args, sptr) - : va_arg(args, int); - result += AppendSignedDecimal(&buff, buff_end, dval); + dval = have_ll ? va_arg(args, s64) + : have_z ? va_arg(args, sptr) + : va_arg(args, int); + result += AppendSignedDecimal(&buff, buff_end, dval, width); break; } case 'u': case 'x': { - uval = have_z ? va_arg(args, uptr) - : va_arg(args, unsigned); + uval = have_ll ? va_arg(args, u64) + : have_z ? va_arg(args, uptr) + : va_arg(args, unsigned); result += AppendUnsigned(&buff, buff_end, uval, - (*cur == 'u') ? 10 : 16, 0); + (*cur == 'u') ? 10 : 16, width); break; } case 'p': { - RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp); + RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp); result += AppendPointer(&buff, buff_end, va_arg(args, uptr)); break; } case 's': { - RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp); + RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp); result += AppendString(&buff, buff_end, va_arg(args, char*)); break; } case 'c': { - RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp); + RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp); result += AppendChar(&buff, buff_end, va_arg(args, int)); break; } case '%' : { - RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp); + RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp); result += AppendChar(&buff, buff_end, '%'); break; } diff --git a/lib/ubsan/CMakeLists.txt b/lib/ubsan/CMakeLists.txt index 616e0650c..2cce0e983 100644 --- a/lib/ubsan/CMakeLists.txt +++ b/lib/ubsan/CMakeLists.txt @@ -15,7 +15,10 @@ set(UBSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS}) set(UBSAN_RUNTIME_LIBRARIES) if(CAN_TARGET_X86_64) - add_library(clang_rt.ubsan-x86_64 STATIC ${UBSAN_SOURCES}) + add_library(clang_rt.ubsan-x86_64 STATIC + ${UBSAN_SOURCES} + $<TARGET_OBJECTS:RTSanitizerCommon.x86_64> + ) set_target_compile_flags(clang_rt.ubsan-x86_64 ${UBSAN_CFLAGS} ${TARGET_X86_64_CFLAGS} ) @@ -23,7 +26,10 @@ if(CAN_TARGET_X86_64) endif() if(CAN_TARGET_I386) - add_library(clang_rt.ubsan-i386 STATIC ${UBSAN_SOURCES}) + add_library(clang_rt.ubsan-i386 STATIC + ${UBSAN_SOURCES} + $<TARGET_OBJECTS:RTSanitizerCommon.x86_64> + ) set_target_compile_flags(clang_rt.ubsan-i386 ${UBSAN_CFLAGS} ${TARGET_I386_CFLAGS} ) diff --git a/lib/ubsan/ubsan_diag.cc b/lib/ubsan/ubsan_diag.cc index 05d81320c..da0a6c32c 100644 --- a/lib/ubsan/ubsan_diag.cc +++ b/lib/ubsan/ubsan_diag.cc @@ -12,9 +12,9 @@ //===----------------------------------------------------------------------===// #include "ubsan_diag.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_libc.h" #include <stdio.h> -#include <unistd.h> -#include <limits.h> using namespace __ubsan; @@ -37,7 +37,7 @@ Diag &Diag::operator<<(const Value &V) { /// Hexadecimal printing for numbers too large for fprintf to handle directly. static void PrintHex(UIntMax Val) { #if HAVE_INT128_T - fprintf(stderr, "0x%08x%08x%08x%08x", + Printf("0x%08x%08x%08x%08x", (unsigned int)(Val >> 96), (unsigned int)(Val >> 64), (unsigned int)(Val >> 32), @@ -48,55 +48,64 @@ static void PrintHex(UIntMax Val) { } Diag::~Diag() { - // FIXME: This is non-portable. - bool UseAnsiColor = isatty(STDERR_FILENO); + bool UseAnsiColor = PrintsToTty(); if (UseAnsiColor) - fprintf(stderr, "\033[1m"); + RawWrite("\033[1m"); if (Loc.isInvalid()) - fprintf(stderr, "<unknown>:"); + RawWrite("<unknown>:"); else { - fprintf(stderr, "%s:%d:", Loc.getFilename(), Loc.getLine()); + Printf("%s:%d:", Loc.getFilename(), Loc.getLine()); if (Loc.getColumn()) - fprintf(stderr, "%d:", Loc.getColumn()); + Printf("%d:", Loc.getColumn()); } if (UseAnsiColor) - fprintf(stderr, "\033[31m"); - fprintf(stderr, " fatal error: "); + RawWrite("\033[31m"); + RawWrite(" fatal error: "); if (UseAnsiColor) - fprintf(stderr, "\033[0;1m"); + RawWrite("\033[0;1m"); for (const char *Msg = Message; *Msg; ++Msg) { - if (*Msg != '%') - fputc((unsigned char)*Msg, stderr); - else { + if (*Msg != '%') { + char Buffer[64]; + unsigned I; + for (I = 0; Msg[I] && Msg[I] != '%' && I != 63; ++I) + Buffer[I] = Msg[I]; + Buffer[I] = '\0'; + RawWrite(Buffer); + Msg += I - 1; + } else { const Arg &A = Args[*++Msg - '0']; switch (A.Kind) { case AK_String: - fprintf(stderr, "%s", A.String); + Printf("%s", A.String); break; case AK_SInt: // 'long long' is guaranteed to be at least 64 bits wide. if (A.SInt >= INT64_MIN && A.SInt <= INT64_MAX) - fprintf(stderr, "%lld", (long long)A.SInt); + Printf("%lld", (long long)A.SInt); else PrintHex(A.SInt); break; case AK_UInt: if (A.UInt <= UINT64_MAX) - fprintf(stderr, "%llu", (unsigned long long)A.UInt); + Printf("%llu", (unsigned long long)A.UInt); else PrintHex(A.UInt); break; - case AK_Float: - fprintf(stderr, "%Lg", (long double)A.Float); + case AK_Float: { + // FIXME: Support floating-point formatting in sanitizer_common's + // printf, and stop using snprintf here. + char Buffer[32]; + snprintf(Buffer, sizeof(Buffer), "%Lg", (long double)A.Float); + Printf("%s", Buffer); break; + } case AK_Pointer: - fprintf(stderr, "0x%zx", (uptr)A.Pointer); + Printf("0x%zx", (uptr)A.Pointer); break; } } } - fputc('\n', stderr); + RawWrite("\n"); if (UseAnsiColor) - fprintf(stderr, "\033[0m"); - fflush(stderr); + Printf("\033[0m"); } diff --git a/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cc index ae0f1f6c3..a8df7831d 100644 --- a/lib/ubsan/ubsan_handlers.cc +++ b/lib/ubsan/ubsan_handlers.cc @@ -19,18 +19,6 @@ using namespace __sanitizer; using namespace __ubsan; -NORETURN void __sanitizer::Die() { - __builtin_trap(); -} - -NORETURN void __sanitizer::CheckFailed(const char *File, int Line, - const char *Cond, u64 V1, u64 V2) { - Diag(SourceLocation(File, Line, 0), - "CHECK failed: %0 (with values %1 and %2)") - << Cond << V1 << V2; - Die(); -} - namespace __ubsan { const char *TypeCheckKinds[] = { "load of", "store to", "reference binding to", "member access within", |