summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sanitizer_common/sanitizer_printf.cc44
-rw-r--r--lib/ubsan/CMakeLists.txt10
-rw-r--r--lib/ubsan/ubsan_diag.cc57
-rw-r--r--lib/ubsan/ubsan_handlers.cc12
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",